Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redux persist rehydrate previous auth state too late

I have setup routes that are meant to be authenticated to redirect user to login page if unauthenticated. I have also setup redux-persist to auto dehydrate my auth state so user remains login on refresh. The problem is this rehydration is too late and user is already redirected to login page

enter image description here

The 1st location change is to an authenticated route, the 2nd is to login. Notice rehydrate comes after these. Ideally it should be right after @@INIT at least?

like image 798
Jiew Meng Avatar asked Apr 02 '17 13:04

Jiew Meng


People also ask

Does redux state persist on refresh?

With the Redux Persist library, developers can save the Redux store in persistent storage, for example, the local storage. Therefore, even after refreshing the browser, the site state will still be preserved.

How do you hydrate a redux store?

Hydrating the state after the store was created, can be achieved by creating a main reducer that can bypass the top level reducers, and replace the whole state. Reducers are functions that get the current state, combine it with the payload of an action, and return a new state.


1 Answers

The persistStore function which is used to make your store persistent have a third param callback which is invoked after store rehydration is done. You have to start your app with some sort of preloader, which waits for rehydration to happen and renders your full application only after it finishes.

redux-persist docs even have a recipe for this scenario. In your case all the react-router stuff should be rendered inside initial loader as well:

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} />, ... );
like image 161
fkulikov Avatar answered Sep 20 '22 20:09

fkulikov