Effect
- A useEffect without a dependency array runs after every render, and its returned cleanup function runs before the next effect call or when the component unmounts, making it useful for tasks that must run on every update and for cleaning up resources. If there’s a dependency array, the effect only runs when one of the dependencies changes, and the cleanup function runs before the effect re-runs for those changes or when the component unmounts.
- With
useEffect (passive effects), Preact runs children’s cleanups and effects before the parent’s during the commit phase.
- (Toggle Demo) A Toggle can be implemented in two ways. In the controlled pattern, the parent component owns the checked value (from local state or a signal) and passes it down along with an onChange that updates the parent’s state, so the Toggle simply reflects and reports changes. In the self-controlled pattern, the Toggle manages its own checked state internally with useState, optionally calling an onChange to notify the parent. The key difference is where the single source of truth for the value lives — in the parent for controlled components or inside the component itself for self-controlled ones.
- When studying effects, remember that they always run after the browser updates the screen, and their optional cleanup functions run before the next time the effect executes or when the component is removed. Without dependencies, an effect runs after every render. With an empty dependency list, it runs only once after the first mount and cleans up only on unmount. With specific dependencies, it runs only when those values change, and cleans up right before re-running for the new values.
- Local signal(...) inside the component body → broken since the component function runs on every render. Module-level signal(...) (outside the component) → shared across all instances sin a module variable is created once per module, not per component instance.
useMemo is being used to create the signal only once per component instance, instead of re-creating it on every render. useMemo(factory, deps) tells Preact:
- On the first render, call
factory() (here signal(startOpen)) and store the returned value.
- On later renders, return the stored value instead of calling factory() again — unless something in the dependency array (deps) changes.
- Passing an empty array means the dependencies never change, so factory() runs only once for the entire life of this component instance. That’s why you need to pass an empty array, which is important.
- If you wrap your handler in useCallback, like below, then its identity stays the same between renders unless something in the dependency array changes.
const handler = useCallback((e: KeyboardEvent) => {
setLastKey(e.key);
console.log(`keydown: ${e.key} (listener ${listenerNum})`);
}, []);
- Differences between
useCallback and useMemo
- For functions: useCallback(fn, deps) is essentially shorthand for useMemo(() => fn, deps), just more semantic.
- For values: use useMemo to cache an expensive calculation’s result, not useCallback.
onInput fires on every keystroke/paste/delete (live as you type). onChange fires when the value is committed — typically on blur (losing focus), not on every stroke, such that it will run when you lose focus of the textfield and the value has been changed.
- Component Data Flow

- Differences between
useEffect and useLayoutEffect:
useEffect runs asynchronously after the browser has painted the updated UI. This means the user may briefly see the unmodified or partially updated view before your effect makes further changes. It does not block painting, so it’s better for side effects that don’t need to be visible instantly — like fetching data, logging, or setting timers.
useLayoutEffect runs synchronously after the DOM update but before the browser paints. It blocks the paint until it’s done, so any visual changes happen in the same frame as the DOM update. This is important for avoiding flicker when you need immediate visual updates, measurements, or DOM mutations that should be reflected in the very first paint.
-
useRef is a React/Preact hook that returns a stable, mutable object with a .current property, which persists for the lifetime of the component and can be used to store values or references without causing re-renders when updated.