---
title: use-memo
version: rc
---
Validates that the `useMemo` hook is used with a return value. See [`useMemo` docs](/reference/react/useMemo) for more information.
This rule is available in `eslint-plugin-react-hooks` v6.
## Rule Details {/*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 {/*invalid*/}
Examples of incorrect code for this rule:
```js {expectedErrors: {'react-compiler': [3]}}
// ❌ No return value
function Component({ data }) {
const processed = useMemo(() => {
data.forEach(item => console.log(item));
// Missing return!
}, [data]);
return
{processed}
; // Always undefined
}
```
### Valid {/*valid*/}
Examples of correct code for this rule:
```js
// ✅ Returns computed value
function Component({ data }) {
const processed = useMemo(() => {
return data.map(item => item * 2);
}, [data]);
return
{processed}
;
}
```
## Troubleshooting {/*troubleshooting*/}
### I need to run side effects when dependencies change {/*side-effects*/}
You might try to use `useMemo` for side effects:
{/* TODO(@poteto) fix compiler validation to check for unassigned useMemos */}
```js {expectedErrors: {'react-compiler': [4]}}
// ❌ Wrong: Side effects in useMemo
function 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:
```js
// ✅ Good: Side effects in event handlers
function Component({user}) {
const handleClick = () => {
analytics.track('ButtonClicked', {userId: user.id});
// Other click logic...
};
return ;
}
```
If the side effect sychronizes React state with some external state (or vice versa), use `useEffect`:
```js
// ✅ Good: Synchronization in useEffect
function Component({theme}) {
useEffect(() => {
localStorage.setItem('preferredTheme', theme);
document.body.className = theme;
}, [theme]);
return