Rules
use-memo
This rule is currently in beta and only available in v3.0.0 beta releases.
Full Name in @eslint-react/eslint-plugin@beta
@eslint-react/use-memoFull Name in eslint-plugin-react-x@beta
react-x/use-memoPresets
x
recommended
recommended-typescript
recommended-type-checked
strict
strict-typescript
strict-type-checked
Description
Validates that useMemo is called with a callback that returns a value.
useMemo is designed for computing and caching expensive values between renders. Without a return value, useMemo always returns undefined, which defeats its purpose and likely indicates the wrong hook is being used.
There are two violations this rule catches:
- Missing return value — the callback passed to
useMemodoes not return a value (implicitly returnsundefined). - Result not assigned — the return value of
useMemois discarded (not assigned to a variable), which means the memoized value is never used.
If you need to run side effects when dependencies change, use useEffect instead.
Examples
Failing
// ❌ No return value in the callback
function Component({ data }) {
const processed = useMemo(() => {
data.forEach(item => console.log(item));
// Missing return!
}, [data]);
return <div>{processed}</div>; // Always undefined
}// ❌ useMemo result not assigned to a variable (side-effect usage)
function Component({ user }) {
useMemo(() => {
analytics.track("UserViewed", { userId: user.id });
}, [user.id]);
return <div />;
}// ❌ useMemo result not assigned even when callback has a return
function Component({ user }) {
useMemo(() => {
return analytics.track("UserViewed", { userId: user.id });
}, [user.id]);
return <div />;
}Passing
// ✅ Returns a computed value
function Component({ data }) {
const processed = useMemo(() => {
return data.map(item => item * 2);
}, [data]);
return <div>{processed}</div>;
}// ✅ Arrow function with concise body (implicitly returns)
function Component({ items }) {
const sorted = useMemo(() => [...items].sort(), [items]);
return <div>{sorted.join(", ")}</div>;
}// ✅ Use useEffect for side effects instead
function Component({ user }) {
useEffect(() => {
analytics.track("UserViewed", { userId: user.id });
}, [user.id]);
return <div />;
}Implementation
Further Reading
See Also
use-state
Enforces correct usage of theuseStatehook.no-unnecessary-use-memo
Disallows unnecessary usage ofuseMemo.exhaustive-deps
Validates that dependency arrays for React hooks contain all necessary dependencies.rules-of-hooks
Validates that components and hooks follow the Rules of Hooks.