[]previous and next page

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.

For agentsUpdated

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.

src/derived.tsxtsx
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 const declarations 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.