# react-hooks/void-use-memo

> Require `useMemo()` callbacks to return a value, and the value to be used

`useMemo()` caches what its callback returns. A callback that returns nothing caches `undefined`, which usually means a forgotten `return`, or a side effect that belongs in `useEffect()`. React can skip or repeat the callback, so a side effect in it won't run when you expect.

The rule also reports a `useMemo()` call if its result is never used.

{/* Generated by src/codegen/lint-rule-docs.ts. Do not edit this section. */}

## Configure

Off by default. To turn it on:

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

{/* End of the generated section. */}

## Examples

Reported:

{/* bad */}
```jsx
import { useMemo } from "react";

function Report({ rows }) {
  const visible = useMemo(() => {
    rows.filter(row => !row.hidden);
  }, [rows]);
  return <Table rows={visible} />;
}
```

{/* bad */}
```jsx
import { useMemo } from "react";

function Report({ rows }) {
  useMemo(() => rows.filter(row => !row.hidden), [rows]);
  return <Table rows={rows} />;
}
```

Not reported:

{/* good */}
```jsx
import { useMemo } from "react";

function Report({ rows }) {
  const visible = useMemo(() => {
    return rows.filter(row => !row.hidden);
  }, [rows]);
  return <Table rows={visible} />;
}
```

Side effects go in an effect:

{/* good */}
```jsx
import { useEffect } from "react";

function Report({ rows }) {
  useEffect(() => {
    track("report", rows.length);
  }, [rows]);
  return <Table rows={rows} />;
}
```
