Redux resets previous authorization state too late

I have setup routes that are for authentication, to redirect the user to the login page if he is not authenticated. I also installed redux-persist to automatically dehydrate my auth state so that the user remains the login when updating. The problem is that this rehydration is too late and the user is already redirected to the login page

enter image description here

The first change of location refers to the authenticated route, the second to login. After this rehydrate appears. Ideally, this should be right after @@ INIT?

+8
reactjs redux react-redux
source share
2 answers

The persistStore function, which is used to save your storage, has a third callback parameter, which is called after the storage is rehydrated. You have to start your application with some kind of preloader, which is waiting for re-hydration and will make your full application only after its completion.

redux-persist docs even have a recipe for this scenario. In your case, all react-router elements should also appear inside the bootloader:

 export default class Preloader extends Component { constructor() { super() this.state = { rehydrated: false } } componentWillMount(){ persistStore(this.props.store, {}, () => { this.setState({ rehydrated: true }); }) } render() { if(!this.state.rehydrated){ return <Loader />; } return ( <Provider store={store}> <ConnectedRouter history={history}> <App /> </ConnectedRouter> </Provider> ); } } const store = ...; // creating the store but not calling persistStore yet ReactDOM.render(<Preloader store={store} />, ... ); 
+10
source share

When the user refreshes the page, the first LOCATION_CHANGE will light up because you are synchronizing the history with the repository. However, it only synchronizes the history and does not redirect the user to anywhere else.

The only thing that matters is the second LOCATION_CHANGE , which should happen after persistStore() . The good news: persistStore() has a callback.

 const store = ... // persist store persistStore(store, options, () => { const states = store.getState(); // if authenticated, do nothing, // if not, redirect to login page if (!states.auth.isAuthenticated) { // redirect to login page } }); render(...); 

Hope this helps solve your problem.

0
source share

All Articles