useMemo and useCallback
Inside a component, a const computed from signals or props is a derived value: the compiler turns it into a memo when something in JSX or a closure reads it.
Inside a component, a const computed from signals or props is a derived value: the compiler turns it into a
memo when something in JSX or a closure reads it. Write the expression; do not wrap it.
import { useStore } from "@shadow-js/core";
export function Totals() {
const [prices] = useStore([10, 20, 30]);
const total = prices.reduce((sum, price) => sum + price, 0);
const double = total * 2;
return (
<p>
{prices.length} items, total {total}, double {double}
</p>
);
}
The rules, from docs/contracts/forgiving-reactivity.md:
- Only
constdeclarations at the top level of the component body are derived. - A derived value is a memo: it re-runs only when the signals it read change, and it caches.
- Hooks and primitives (
use*,create*,batch,untrack,onMount, ...), functions, classes, JSX and literals are left alone. - Calling a derived value (
double()) returns its value, so both{double}and{double()}work.
Write useMemo yourself when the value is not a top-level const, or when you need its options: equals to
stop propagation when the result is equivalent, lazy to skip the first computation until it is read. Memos
must be pure: writing a signal inside one throws in development builds (WRITE_IN_MEMO).
useCallback and React.memo exist to keep a child from re-rendering when a handler changes identity. Nothing
re-renders, so a handler is a function created once, and it reads current values when it runs. Pass it
down as is.