I’ve read a ton of posts and articles, tried different approaches, inluding useContext, useReducer, etc. but i still can’t understand why state does not change and why the page is not rerendering?
const [access, setAccess] = useState(localStorage.getItem('access'));
useEffect(() => {
setAccess(localStorage.getItem('access'));
}, []);
If i pass [access] to useEffect, it becomes an infinite loop. I’ve added the code in the parent component and passed access as an argument, still doesn’t work. No surprise there are more than 30 pages with similar posts and most of the answers are unclear, outdated or not working for me. AI also failed to solve this tiny problem. I’m using funcional components, most of the info I’ve found i about class-based components.
3
Answers
Is your component server side or clien side?
Check one of these examples here.
localStorage or sessionStorage is readable only when clien side
The reason your React component isn’t re-rendering when you update localStorage is that React doesn’t automatically track changes to localStorage. It only re-renders when the component’s state changes via useState or setState, and differs from the current value.
When you do:
React grabs the initial value from localStorage, but it won’t re-render unless you call setAccess() with a new value.
If you want the component to update when localStorage changes, you can listen to the storage event like this:
However, this doesn’t fire for changes in the same tab, so after updating localStorage, you’ll need to manually update the state:
So all in all it should look like this
Let me know if this helps!
You made a mistake using useEffect. In function components, useEffect works like componentDidMount or componentWillMount in class components. This is , the code inside useEffect is executed when the dependencies of useEffect change.
But in your code, you don’t have any dependency so the useEffect will be executed like componentDidMound, in order words, it will be only once excuted once function component is mounted.
In this caes, if you set initial state value of accces to null or an empty string, the page will be rendered, but since you already set initial state value of access to localStorage.getItem(‘access’), even if you try to setAccess(localStroage.getItem(‘access’) inside useEffect, the page will not rerender.
Therefore, if you want to re-render the page based on changing the access value of localStroage, you need to listen the localStroage change event in useEffect and set the value to access to trigger rerender.
Below is the sample code:
Note: you should use a cleanup function in useEffect to avoid potential mistakes in the future.