Validates that the useMemo hook is used with a return value. See useMemo docs for more information.
Rule Details
Section titled “Rule Details”useMemo is for computing and caching expensive values, not for side effects. Without a return value, useMemo returns undefined, which defeats its purpose and likely indicates you’re using the wrong hook.
Invalid
Section titled “Invalid”Examples of incorrect code for this rule:
// ❌ No return valuefunction Component({ data }) { const processed = useMemo(() => { data.forEach(item => console.log(item)); // Missing return! }, [data]);
return <div>{processed}</div>; // Always undefined}Examples of correct code for this rule:
// ✅ Returns computed valuefunction Component({ data }) { const processed = useMemo(() => { return data.map(item => item * 2); }, [data]);
return <div>{processed}</div>;}Troubleshooting
Section titled “Troubleshooting”I need to run side effects when dependencies change
Section titled “I need to run side effects when dependencies change”You might try to use useMemo for side effects:
// ❌ Wrong: Side effects in useMemofunction Component({user}) { // No return value, just side effect useMemo(() => { analytics.track('UserViewed', {userId: user.id}); }, [user.id]);
// Not assigned to a variable useMemo(() => { return analytics.track('UserViewed', {userId: user.id}); }, [user.id]);}If the side effect needs to happen in response to user interaction, it’s best to colocate the side effect with the event:
// ✅ Good: Side effects in event handlersfunction Component({user}) { const handleClick = () => { analytics.track('ButtonClicked', {userId: user.id}); // Other click logic... };
return <button onClick={handleClick}>Click me</button>;}If the side effect sychronizes React state with some external state (or vice versa), use useEffect:
// ✅ Good: Synchronization in useEffectfunction Component({theme}) { useEffect(() => { localStorage.setItem('preferredTheme', theme); document.body.className = theme; }, [theme]);
return <div>Current theme: {theme}</div>;}