I am looking for a solution to register the route change and apply new state
using setState
and useEffect
. The current code below doesn't update functions of setState
when the route is changed.
For example, I register the pathname
of /
with location.pathname === '/'
within createContext
, if the pathname
is /
the setState
of isHome
is registered true
, however if pathname
is /page-1
setState
is registered false
.
On browser reloads, onMount
the state
is correctly set, however on a route change using Link
this does not. Also, please note that I am using Gatsby and in doing so, importing { Link } from 'gatsby'
CreateContext.js
export const GlobalProvider = ({ children, location }) => {
const prevScrollY = useRef(0);
const [state, setState] = useState({
isHome: location.pathname === '/',
// other states
});
const detectHome = () => {
const homePath = location.pathname === '/';
if (!homePath) {
setState(prevState => ({
...prevState,
isHome: false
}));
}
if (homePath) {
setState(prevState => ({
...prevState,
isHome: true
}));
}
};
useEffect(() => {
detectHome();
return () => {
detectHome();
};
}, [state.isHome]);
return (
<GlobalConsumer.Provider
value={{
dataContext: state,
}}
>
{children}
</GlobalConsumer.Provider>
);
};
If I console.log(state.isHome)
on pathname
/
I get true
, any other pathnames I get false
, however, if I change route, the current isHome
state remains previous, until I scroll and useEffect
applies.
The point of registering the isHome
state is to alter CSS per page.
How can I update state with useEffect
when changing route. Previously, I would have done this with componentDidUpdate
and register prevProps.location.pathname
against props.location.pathname
, however, my understanding is that this is no longer necessary with the useEffect
hook.
Use the useEffect hook to listen for state changes in React. You can add the state variables you want to track to the hook's dependencies array and the logic in your useEffect hook will run every time the state variables change.
The useLayoutEffect function is triggered synchronously before the DOM mutations are painted. However, the useEffect function is called after the DOM mutations are painted. I chose this example to make sure the browser actually has some changes to paint when the button is clicked, hence the animation.
IMPORTANT: After the component is done rendering, it checks each useEffect hook sequentially in order which they are written. Going through each useEffect hook in the component (that has done rendering). If any of the entry in the dependency array has changed, the callback associated with it/passed to it is run.
Either way, we're now safe to use async functions inside useEffect hooks. Now if/when you want to return a cleanup function, it will get called and we also keep useEffect nice and clean and free from race conditions. Enjoy using async functions with React's useEffect from here on out!
The effect you want is "When the location change then update my state", this is translated in useEffect
code like this :
useEffect(() => {
detectHome();
return () => {
detectHome();
};
}, [location]);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With