Redux how to get updated store state in root component

540 views Asked by At

My root App component looks like this:

class App extends Component {
  render() {
    const state = store.getState();
    const { isAuthenticated } = state.auth;

    return (
      <Provider store={store}>
        <BrowserRouter basename="/">
          <Switch>
            {isAuthenticated ? (
              <PrivateRoute
                exact
                path="/library/:user_id"
                component={RessourcesByUser}
              />
            ) : (
              <PublicRoute
                exact
                path="/library/:user_id"
                component={PublicRessourcesByUserPage}
              />
            )}
          </Switch>
        </BrowserRouter>
      </Provider>
    );
  }
}

The problem with isAuthenticated is that when the app is first loaded before the user logs in its value is false.

And it makes sense since the user has not logged in yet.

The problem is that when he logs in, the App component does not mount again (obviously), nor does it get the updated store state in which isAuthenticated is true.

So isAuthenticated here in App component will remain false even though the user is authenticated and its value in the store is true.

It will change to true here once he refreshes because App component will get the updated state then in which isAuthenticated is true.

However, meanwhile this will cause logical bugs such as when he goes to a user's Library right after loading the app and logging-in the first time by clicking on a button that would direct to this path /library/:user_id, he will see the public component PublicRessourcesByUserPage that is meant to be displayed for non-authenticated users instead of RessourcesByUser which is meant for authenticated users.

1

There are 1 answers

0
ourmaninamsterdam On

It's been a while since I've used react-router, but if you want to get the freshest (reactive) state with Redux, then your component will need to be connected to Redux. So something along these lines:

import  { connect } from 'react-redux';

class AuthRoutes extends Component {
  render() {
    return (
      <Switch>
        {this.props.isAuthenticated ? (
          <PrivateRoute
            exact
            path="/library/:user_id"
            component={RessourcesByUser}
          />
        ) : (
          <PublicRoute
            exact
            path="/library/:user_id"
            component={PublicRessourcesByUserPage}
          />
        )}
      </Switch>
    )
  }
}

connect((state) => ({ isAuthenticated: state.isAuthenticated }),null)(AuthRoutes);

---

class App extends Component {
  render() {
    return (
      <Provider store={store}>
        <BrowserRouter basename="/">
          <AuthRoutes />
        </BrowserRouter>
      </Provider>
    );
  }
}

Note: I'm making an assumption that Switch will work OK like this.