Parent-child update order
See original GitHub issueI’m encountering a race condition between parent and children updates using zustand. Let me describe the problem:
I have a PrivateRoute component that redirects when my zustand currentUser state is falsy:
const PrivateRoute = ({ component: RouteComponent, ...rest }) => {
const currentUser = useAuth((state) => state.currentUser);
const render = useCallback(
(routeProps) => {
if (currentUser) {
return <RouteComponent {...routeProps} />;
}
// redirect to login if current user is null
return <Redirect to="/login" />;
},
[currentUser]
);
return <Route {...rest} render={render} />;
};
I have a route protected by this PrivateRoute component like so:
export default function Home() {
const currentUser = useAuth((state) => state.currentUser);
// render something using currentUser
}
And then I have something like this:
<Router>
<PrivateRoute component={Home} />
</Router>
I use firebase for handling auth in my app. Zustand allows me to update the state outside a react component w/c I super love:
auth.onAuthStateChanged(async (user) => {
if (user) {
useAuth.setState({ currentUser: res.data });
} else {
// logged out
useAuth.setState({ currentUser: null });
}
});
This works well initially. But for some reason, the second time the auth state updates (i.e. a second logout), the Home
component updates before its parent PrivateComponent
does:
export default function Home() {
const currentUser = useAuth((state) => state.currentUser);
// this errors out because currentUser turns to null and I don't check its value because
// I expect PrivateComponent to redirect first before getting here.
}
I solved this by passing currentUser
instead from the PrivateComponent
:
...
const render = useCallback(
(routeProps) => {
if (currentUser) {
return <RouteComponent currentUser={currentUser} {...routeProps} />;
}
...
export default function Home({ currentUser }) {
// PrivateComponent redirects before anything happens here
}
This is fine but I’m just wondering if this behavior is expected and why it seems to happen only on the second batch of auth updates.
Issue Analytics
- State:
- Created 3 years ago
- Comments:8 (4 by maintainers)
Top GitHub Comments
Because,
useEffect
runs after React renders (and then browser paints).No. Zombie children can be resolved with
unstable_batchedUpdates
in React 17 and automatic batching in React 18.Got it! Thank you for answering this.