Rules
use-memo
Validates that 'useMemo' is called with a callback that returns a value.
This rule is currently in rc and only available in v3.0.0 rc releases.
Full Name in eslint-plugin-react-x@rc
react-x/use-memoFull Name in @eslint-react/eslint-plugin@rc
@eslint-react/use-memoPresets
x
recommended
recommended-typescript
recommended-type-checked
strict
strict-typescript
strict-type-checked
Rule Details
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.
Common Violations
Invalid
// ❌ 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 />;
}Valid
// ✅ 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 />;
}Resources
Further Reading
See Also
react-x/no-unnecessary-use-memo
Disallows unnecessary usage ofuseMemo.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.