Validates that theuseMemo hook is used with a return value. SeeuseMemo docs for more information.
Rule Details
useMemo is for computing and caching expensive values, not for side effects. Without a return value,useMemo returnsundefined, which defeats its purpose and likely indicates you’re using the wrong hook.
Invalid
Examples of incorrect code for this rule:
// ❌ No return value
functionComponent({data}){
constprocessed =useMemo(()=>{
data.forEach(item=>console.log(item));
// Missing return!
},[data]);
return<div>{processed}</div>;// Always undefined
}Valid
Examples of correct code for this rule:
// ✅ Returns computed value
functionComponent({data}){
constprocessed =useMemo(()=>{
returndata.map(item=>item *2);
},[data]);
return<div>{processed}</div>;
}Troubleshooting
I need to run side effects when dependencies change
You might try to useuseMemo for side effects:
// ❌ Wrong: Side effects in useMemo
functionComponent({user}){
// No return value, just side effect
useMemo(()=>{
analytics.track('UserViewed',{userId:user.id});
},[user.id]);
// Not assigned to a variable
useMemo(()=>{
returnanalytics.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 handlers
functionComponent({user}){
consthandleClick =()=>{
analytics.track('ButtonClicked',{userId:user.id});
// Other click logic...
};
return<buttononClick={handleClick}>Click me</button>;
}If the side effect sychronizes React state with some external state (or vice versa), useuseEffect:
// ✅ Good: Synchronization in useEffect
functionComponent({theme}){
useEffect(()=>{
localStorage.setItem('preferredTheme',theme);
document.body.className =theme;
},[theme]);
return<div>Current theme:{theme}</div>;
}