liveBook · Manning

Dependency array

As explained in React in Depth

A dependency array is the optional second argument to a React effect or memoization hook that determines when its computation is rerun.

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

How React in Depth covers it

How deep it goes
Distinguishes omitted, empty, and nonempty arrays; explains referential equality, stable-value exceptions, and maintenance pitfalls.
Examples
Uses employee-list filtering, render tracking, and a deletion callback with a stable state setter.
What it assumes
Assumes familiarity with React hooks and JavaScript values, while explaining the array forms and reference-stability implications.
What you can do after
Apply it in React hooks to select rerun conditions and diagnose missing or needlessly changing dependencies.
How it connects
Connects useEffect, useLayoutEffect, useMemo, and useCallback to memoization, referential equality, and ESLint checks.

Also explained in

Compare how 3 books explain dependency array →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of React in Depth. The section links point to the parts of the book it draws on.