react-hooks/use-memo

Require useMemo() callbacks to take no parameters, be synchronous, and not reassign outer variables

Also called react_hooks/use-memo, react/use-memo

React calls the function you pass to useMemo() with no arguments, keeps what it returns, and skips the call while the dependencies stay the same. Three kinds of callback don't fit that:

  • A callback with parameters. They're always undefined.
  • An async or generator function. The cached value is a promise or an iterator, not the result.
  • A callback that assigns to a variable declared outside of it. The assignment doesn't happen on a render where React reuses the cached value.

Configure#

Off by default. To turn it on:

bunfig.toml
[lint.rules]
"react-hooks/use-memo" = "error" # or "warn"

Examples#

example.jsx1 problem
import { useMemo } from "react";

function Report({ id }) {
  const rows = useMemo(async () => {
    return await loadRows(id);
  }, [id]);
  return <Table rows={rows} />;
}
example.jsx1 problem
import { useMemo } from "react";

function Report({ rows }) {
  const sorted = useMemo(list => list.toSorted(), [rows]);
  return <Table rows={sorted} />;
}
example.jsx1 problem
import { useMemo } from "react";

function Report({ rows }) {
  let total = 0;
  const visible = useMemo(() => {
    total = rows.length;
    return rows.filter(row => !row.hidden);
  }, [rows]);
  return <Table rows={visible} total={total} />;
}
example.jsxNo problems
import { useMemo } from "react";

function Report({ rows }) {
  const sorted = useMemo(() => rows.toSorted(), [rows]);
  const total = rows.length;
  return <Table rows={sorted} total={total} />;
}