Solid.js Memos — Derived and Cached Values
In this tutorial, you will learn about Solid.js Memos. We cover key concepts, practical examples, and best practices to help you master this topic.
Learn Solid.js memos: create cached computed values with createMemo, derive state from signals, and optimize performance with lazy evaluation.
In this lesson, you'll use createMemo() to create derived values that cache their results and only re-compute when dependencies change.
What You'll Learn
How to create memos, understand Caching and lazy evaluation, use memos in templates, and optimize expensive computations.
Why It Matters
Memos cache computed values and only re-calculate when dependencies change. This prevents unnecessary recalculations and improves performance for expensive operations.
Real-World Use
Doda Browser uses memos for search filtering: the filtered results list is a memo of the search query and the full item list.
flowchart LR
A[Signal A] --> C[Memo]
B[Signal B] --> C
C --> D[Cached Result]
C -->|Dependency Changes| E[Re-compute]
style C fill:#2c4f7c,color:#fff
Basic Memo
import { createSignal, createMemo } from "solid-js";
const [items, setItems] = createSignal([1, 2, 3, 4, 5]);
const total = createMemo(() => items().reduce((a, b) => a + b, 0));
console.log(total()); // 15
// total() is cached until items() changes
Memo with Multiple Dependencies
const [price, setPrice] = createSignal(100);
const [quantity, setQuantity] = createSignal(2);
const [taxRate, setTaxRate] = createSignal(0.08);
const totalPrice = createMemo(() => {
const subtotal = price() * quantity();
return subtotal + subtotal * taxRate();
});
totalPrice() only re-computes when price, quantity, or taxRate changes.
Memo for Derived Display Values
function TodoList() {
const [todos, setTodos] = createSignal([]);
const [filter, setFilter] = createSignal("all");
const filteredTodos = createMemo(() => {
switch (filter()) {
case "active": return todos().filter(t => !t.completed);
case "completed": return todos().filter(t => t.completed);
default: return todos();
}
});
const stats = createMemo(() => ({
total: todos().length,
active: todos().filter(t => !t.completed).length,
completed: todos().filter(t => t.completed).length,
}));
return (
<div>
<p>{stats().active} remaining</p>
<For each={filteredTodos()}>{todo => <TodoItem todo={todo} />}</For>
</div>
);
}
Expensive Computation
const expensiveResult = createMemo(() => {
console.log("Computing...");
// Simulate expensive operation
const data = doHeavyComputation(items());
return data;
});
// First access: "Computing..." logged
// Second access: no log (cached)
// After items change: "Computing..." logged again
Common Mistakes
- Using effects instead of memos for derived values: Effects don't return values for use in templates. Use memos for computed display values.
- Not caching expensive computations: Filtering or sorting arrays in templates runs on every render. Use a memo.
- Mutating memo return values: Memos return cached objects. Mutating them persists across re-computations. Return new objects.
- Creating memos that don't read signals: A memo that reads no signals computes once and never updates.
- Over-memoizing: Simple arithmetic doesn't need memoization. Use memos for expensive operations.
Practice Questions
How does createMemo differ from createSignal? Answer: Signals hold state with getter/setter. Memos derive values from signals and cache the result.
When does a memo re-compute? Answer: Only when one of its signal dependencies changes. Otherwise, it returns the cached value.
Is a memo lazy or eager? Answer: Lazy. The computation doesn't run until the first time the memo is read.
Can a memo depend on another memo? Answer: Yes. Memos can depend on other memos, forming a dependency graph.
Challenge
Build a shopping cart with memos for subtotal, tax (8%), shipping (free over $50, otherwise $5), and total. Each memo depends on the previous one.
Mini Project
Create a real-time search filter: a list of 100 names, a signal for the search query, a memo that filters the list, and a display component showing the filtered count and names.
FAQ
What's Next
Learn about Solid.js Batching for grouping signal updates and optimizing performance.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro