I am trying to build a global navigation system for my react app where I store the states in local storage and url. now when I need to go back, the first time when I click back it works. I restore the previous states. But from next back click i have to do it twice before I can go back to the previous state. the history is not updating on the first back click. the url is also not changing on first click.
my code is as follows –
const useMyHook = (key) => {
const [st1, setSt1] = useState(null);
const [st2, setSt2] = useState(null);
const [initialLoad, setInitialLoad] = useState(true); // to find if it is loaded
useEffect(() => {
const storedFilters = JSON.parse(localStorage.getItem(key));
if (storedFilters && initialLoad) {
setSt1(storedFilters.st1);
setSt2(storedFilters.st2);
}
setInitialLoad(false); // once loaded set it to false
}, [initialLoad, key]);
useEffect(() => {
const updateQueryParams = () => {
const queryParams = new URLSearchParams();
if (st1) queryParams.set('state1', st1);
if (st2) queryParams.set('state2', st2);
const queryString = queryParams.toString();
const newUrl = `${window.location.pathname}?${queryString}`;
window.history.pushState({ path: newUrl }, '', newUrl);
localStorage.setItem(key, JSON.stringify({ st1, st2 }));
};
updateQueryParams();
}, [st1, st2, key]);
useEffect(() => {
const handlePopState = () => {
const queryParams = new URLSearchParams(window.location.search);
setApps(queryParams.get('state1') ? parseInt(queryParams.get('state1')) : null);
setLoc(queryParams.get('state2') ? parseInt(queryParams.get('state2')) : null);
};
window.addEventListener('popstate', handlePopState);
return () => {
window.removeEventListener('popstate', handlePopState);
}
}, []);
return { st1, setSt1, st2, setSt2 };
};
2
Answers
I believe this is happening because your app is running in strict mode:
you can put an
if
to make sure that this combination of dependencies is newor you can fix your logic so you don’t use useEffect other than when interacting with external systems. Read this from the official docs for more information: You Might Not Need an Effect
hope this might help!
The issue you’re experiencing may be related to how you’re handling the initialLoad state in your useMyHook custom hook. It seems that the first time you click the back button, the initialLoad state is set to false, and subsequent clicks work as expected. However, on subsequent visits to the page, the initialLoad state is set to true again, causing the initial state to be restored.
To resolve this issue, you can modify your code as follows:
In this updated code, the initialLoad state is set to false as soon as the component mounts, regardless of whether there are stored filters in the localStorage or not. This ensures that subsequent visits to the page won’t trigger the restoration of the initial state.
Additionally, the initialLoad dependency has been removed from the first useEffect hook because it’s not necessary to include it there. The effect only needs to run once, regardless of the initialLoad state.