Ahmed Gaafer
Ahmed Gaafer

Reputation: 1661

ReactJS: using localStorage to save data breaks with error Maximum update depth exceeded

I have a component Home that I can render in different ways depending on the state.

I am trying to set the state of Home from localStorage


/*
The AuthContext


const globalState = {
  email: null,
  token: null
};
*/

export default function Home() {

  const [user, setUser] = useContext(AuthContext);
  useEffect(() => {
    const token = localStorage.getItem('token') || null;
    const email = localStorage.getItem('email') || null;
    setUser({email, token});
  })

}

This error keeps popping up though and I don't know how to solve it

Maximum update depth exceeded. This can happen when a component calls setState inside useEffect

I tried removing the useEffect but another error popped up

Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate

I know that this error is caused by calling the setUser repeatedly.

But I am not sure how to call the setUser only once.

Upvotes: 0

Views: 570

Answers (1)

Ori Drori
Ori Drori

Reputation: 191976

The useEffect() is called whenever the item renders, and setting the state causes the component to re-render. Add an empty dependencies arrays to the useEffect block. This will allow to block to run only on initial render.

const [user, setUser] = useContext(AuthContext);
useEffect(() => {
  const token = localStorage.getItem('token') || null;
  const email = localStorage.getItem('email') || null;
  setUser({email, token});
}, [])

Since this should happen only once, and the useState is a bit redundant, you can get the same result with useMemo instead. This is a bit less idiomatic, because getting data from localStorage is a side effect, but it's simpler in a case like this.

const user = useMemo(() => {
  const token = localStorage.getItem('token') || null;
  const email = localStorage.getItem('email') || null;
  
  return { email, token };
}, [])

Upvotes: 3

Related Questions