use-memo
Validates that 'useMemo' is called with a callback that returns a value.
Full Name in eslint-plugin-react-x
react-x/use-memoFull Name in @eslint-react/eslint-plugin
@eslint-react/use-memoPresets
x
recommended
recommended-typescript
recommended-type-checked
strict
strict-typescript
strict-type-checked
Rule Details
This rule ensures that useMemo() callbacks follow React's requirements. It checks for several common mistakes:
- Callbacks should not accept parameters (useMemo callbacks are called with no arguments)
- Callbacks should not be async or generator functions (must return a value synchronously)
- Callbacks should not reassign variables declared outside the callback (must be pure)
- Callbacks should return a value (useMemo is for computing values, not side effects)
- The result of useMemo should be used (not discarded)
Common Violations
Invalid
Callback with parameters
import { useMemo } from "react";
function Component({ a, b }) {
const x = useMemo((c) => a + c, [a]);
// ^^ Callbacks with parameters are not supported
return <div>{x}</div>;
}Async or generator callback
import { useMemo } from "react";
function Component({ a }) {
const x = useMemo(async () => {
// ^^^^^^^^^^^^^ Async and generator functions are not supported
return await fetchData(a);
}, [a]);
return <div>{x}</div>;
}Reassigning outer variables
import { useMemo } from "react";
function Component() {
let x;
const y = useMemo(() => {
x = [];
// ^^^ Cannot reassign variable
return true;
}, []);
return <div>{x}{y}</div>;
}No return value
import { useMemo } from "react";
function Component({ data }) {
const processed = useMemo(() => {
data.forEach((item) => console.log(item));
// Missing return! Callback must return a value.
}, [data]);
return <div>{processed}</div>; // Always undefined
}Result not assigned
import { useMemo } from "react";
function Component({ user }) {
useMemo(() => {
// ^^^^^^ useMemo() result is unused
return heavyComputation(user);
}, [user]);
return <div />;
}Valid
Returns a computed value
import { useMemo } from "react";
function Component({ data }) {
const processed = useMemo(() => {
return data.map((item) => item * 2);
}, [data]);
return <div>{processed}</div>;
}Arrow function with concise body
import { useMemo } from "react";
function Component({ items }) {
const sorted = useMemo(() => [...items].sort(), [items]);
return <div>{sorted.join(", ")}</div>;
}Reads outer variables without reassigning
import { useMemo } from "react";
function Component({ a, b }) {
const sum = useMemo(() => a + b, [a, b]);
return <div>{sum}</div>;
}Resources
Further Reading
See Also
react-x/use-state
Enforces correct usage ofuseState, including destructuring, symmetric naming of the value and setter, and wrapping expensive initializers in a lazy initializer function.