question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Parent-child update order

See original GitHub issue

I’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:closed
  • Created 3 years ago
  • Comments:8 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
dai-shicommented, May 31, 2022

Why is it delayed?

Because, useEffect runs after React renders (and then browser paints).

Isnt this just #302 ?

No. Zombie children can be resolved with unstable_batchedUpdates in React 17 and automatic batching in React 18.

1reaction
markstevecommented, Sep 7, 2020

Got it! Thank you for answering this.

Read more comments on GitHub >

github_iconTop Results From Across the Web

In what sequence batch update sets are previewed/committed
Hello,. Batched update sets are previewed as a whole. So if you have 1 parent and 2 child update sets, the entire package...
Read more >
Update parent state from multiple child components at same ...
In my child component, I have a form and for the data, I've created a local state. Let's call this child component ....
Read more >
Parent-child update order #180 - pmndrs/zustand - GitHub
I'm encountering a race condition between parent and children updates using zustand. Let me describe the problem: I have a PrivateRoute ...
Read more >
Changing a Support Order - Florida Department of Revenue
An order to pay child support can be changed (or modified) by the court or administrative agency that issued the order if the...
Read more >
Update state from child to parent with React Context - Medium
Update state from child to parent with React Context · onClick function in order to update parent state · Parent colour is now...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found