A dependency array controls when a React effect runs again or a memoized value is recalculated. It is used with useEffect, useLayoutEffect, useMemo, and useCallback. The choice affects both correctness and performance: omit a changing value and the hook may not update when needed; include an unstable value and it may run more often than intended. section 3.3 section 3.3.4
The three forms mean different things:
- No array: run on every render. This can suit an effect that tracks every render, including renders caused by a parent. Omitting the array from useMemo instead defeats the point of memoization. section 3.3.2
- Empty array (`[]`): run on mount, not on later renders. An effect's cleanup can still run on unmount. section 3.3
- Nonempty array (`[id]`): run on mount and again when any listed dependency changes. React checks changes using referential equality, so a newly created function or object can count as changed even when it looks equivalent. section 3.3 section 3.3.3
Filter only when the inputs change
In an employee list, `const filteredList = useMemo(() => employeeList.filter(({ isTemporary }) => showTempOnly ? isTemporary : true), [employeeList, showTempOnly]);` recalculates the list when either the source list or the temporary-worker filter changes. This is useful when filtering a large list would otherwise be repeated on unrelated renders. section 3.2.4
List the changing values a hook uses, but do not add values known to remain stable across renders. A useState setter is stable, as is the object returned by useRef—even though the ref's `current` property can change. Keeping arrays accurate takes maintenance: when an effect starts using a new prop, update its dependencies too. ESLint can flag omissions in the editor. Memoize judiciously; optimization has its own overhead. section 3.3.3 section 3.3.4 section 3.4
const [items, setItems] = useState(["Clean gutter", "Do dishes"]);
...
const onDelete = useCallback(
(item) => setItems( #1
(list) => list.filter((i) => i !== item),
),
[] #2
);
The deletion callback uses a functional state update and an empty dependency array: its state setter remains the same reference across renders. section 3.3.3


