rimmy
rimmy

Reputation: 245

Unable to check if the persisted state has been loaded or not on index/main file using redux-persist in react-native app

I am using redux and redux-persist to save and persist the state. In my app, I need to decide the default screen based on saved state in redux.

For example - If the user has already been logged-in then he should not see the login screen again when he opens the app. I need to directly jump him to next screen.

But even if I am rendering my component in PersistGate, I am getting the initial state defined in my User reducer and user is always being redirected to login screen. On login screen,I am getting the persisted state. The only issue is that I don't find any way to get persisted state in index.js file.

This is my index.js file, in which I have added an alert statement where I am getting the initial state rather than persisted state -

import React, { Component } from "react";
import { Provider } from "react-redux";
import { StyleProvider } from "native-base";
import reduxStore from "./setup/Store";
import { PersistGate } from "redux-persist/integration/react";
import Navigator from "./setup/Routes";
import SplashScreen from "react-native-splash-screen";
import Walkthrough from "./screens/Walkthrough/Walkthrough";

export default class Main extends Component {
  componentWillMount() {
    SplashScreen.hide();
  }

  render() {
    const Login = Navigator("CustomerLogin");
    const Profile = Navigator("Profile");
    const Home = Navigator("CustomerHome");
    return (
      <Provider store={reduxStore.store}>
        <PersistGate persistor={reduxStore.persistor}>
          {alert(JSON.stringify(reduxStore.store.getState().User))}
          {reduxStore.store.getState().User.is_logged_in &&
          !reduxStore.store.getState().User.is_registered ? (
            <Profile />
          ) : reduxStore.store.getState().User.is_registered ? (
            <Home />
          ) : reduxStore.store.getState().User.walkthrough_visible ? (
            <Walkthrough navigation={Login} />
          ) : (
            <Login />
          )}
        </PersistGate>
      </Provider>
    );
  }
}

and this is my Store.js file -

import { createStore, applyMiddleware, compose } from "redux";
import storage from "redux-persist/lib/storage"; // defaults to localStorage for web and AsyncStorage for react-native
import Reducers from "./Reducer";
import createSagaMiddleware from "redux-saga";
import rootSaga from "./Sagas";
import { persistStore, persistReducer } from "redux-persist";

const sagaMiddleware = createSagaMiddleware();
const middleWare = [sagaMiddleware];

const persistConfig = {
  key: "root",
  storage
};

const persistedReducer = persistReducer(persistConfig, Reducers);

// Add the autoRehydrate middleware to your redux store
const store = createStore(
  persistedReducer,
  compose(applyMiddleware(...middleWare))
);

sagaMiddleware.run(rootSaga);

let persistor = persistStore(store);

// Enable persistence
export default { store, persistor };

How can I fix this issue?

Upvotes: 0

Views: 3055

Answers (1)

dvvtms
dvvtms

Reputation: 627

state is loaded async, and you need wait until finished. For similar situations see PersistGate loading or onBeforeLift props

https://github.com/rt2zz/redux-persist/blob/master/docs/PersistGate.md

<PersistGate
  loading={<CircularIndicator message={"loading"} />}
  onBeforeLift={onBeforeLift}
  persistor={persistor}
>
<Router />
</PersistGate>

UPDATE2:

better is used state, what is passed down from PersistGate. you can create connected branching component:

        const Branch=({User})=><View>{
          !User.is_registered ? (
          <Profile />
          ) : User.is_registered ? (
          <Home />
          ) : User.walkthrough_visible ? (
          <Walkthrough navigation={Login} />
          ) : (
          <Login />
        )}</View>

    const mapStateToProps = (state) => {
      return {
        User: state.User/// get user
      }
    }

    const BranchWithUser = connect(
      mapStateToProps,
    )(Branch)



export default class Main extends Component {
  componentWillMount() {
    SplashScreen.hide();
  }

  render() {
    const Login = Navigator("CustomerLogin");
    const Profile = Navigator("Profile");
    const Home = Navigator("CustomerHome");
    return (
      <Provider store={reduxStore.store}>
        <PersistGate
          loading={<CircularIndicator message={"loading"} />}
          onBeforeLift={onBeforeLift}
          persistor={persistor}
        >
        <BranchWithUser />
        </PersistGate>
      </Provider>
    );
  }
}

Upvotes: 2

Related Questions