Create your reducer
loginReducer.tsx
export const LOGIN = 'login/LOGIN'; export const SET_LOGGEDIN_USER = 'login/SET_LOGGED_IN_USER'; const initialState = { isLoggedIn: false, user: null, }; const loginReducer = (state = initialState, action: any) => { switch (action.type) { case LOGIN: { return { ...state, isLoggedIn: action.data, }; } case SET_LOGGEDIN_USER: { return { ...state, user: action.data, }; } default: { return state; } } }; export default loginReducer;
loginActions.tsx
import { LOGIN, SET_LOGGEDIN_USER } from './loginReducer'; export const login = (isLoggedIn: boolean) => ({ type: LOGIN, data: isLoggedIn, }); export const setLoggedInUser = (loggedInUser: object) => ({ type: SET_LOGGEDIN_USER, data: loggedInUser, });
Create persist reducer
reducers.tsx
import { combineReducers } from 'redux'; import { persistReducer } from 'redux-persist'; import AsyncStorage from '@react-native-community/async-storage'; import loginReducer from 'src/screens/login/state/loginReducer'; import homeReducer from 'src/screens/home/state/homeReducer'; const rootPersistConfig = { key: 'root', storage: AsyncStorage, blacklist: ['stateLogin', 'stateHome'], }; const loginPersistConfig = { key: 'login', storage: AsyncStorage, whitelist: ['isLoggedIn'], // only persist "isLoggedIn" }; const homePersistConfig = { key: 'home', storage: AsyncStorage, whitelist: ['token', 'userData'], // only persist "token", "userData" }; const rootReducer = combineReducers({ stateLogin: persistReducer(loginPersistConfig, loginReducer), stateHome: persistReducer(homePersistConfig, homeReducer), }); export default persistReducer(rootPersistConfig, rootReducer);
Initiate store
store.tsx
import { compose, createStore, applyMiddleware } from 'redux'; import { createLogger } from 'redux-logger'; import { persistStore } from 'redux-persist'; import Reactotron from 'src/config/reactotron'; import rootReducer from './reducers'; const store = createStore( rootReducer, compose(applyMiddleware(createLogger()), Reactotron.createEnhancer()) ); const persistor = persistStore(store); export { store, persistor };
Usage
import { PersistGate } from 'redux-persist/integration/react'; import { Provider } from 'react-redux'; import { store, persistor } from 'src/redux/store'; ... const App = () => { return ( <Provider store={store}> <PersistGate loading={null} persistor={persistor}> <Routing /> </PersistGate> </Provider> ); };
import React, { useEffect } from 'react'; import { NavigationContainer } from '@react-navigation/native'; import { LoginStack, MainStack } from 'src/routing/stacks'; import { getCurrentAuthUser } from 'src/api'; import { connect } from 'react-redux'; import { login } from 'src/screens/login/state/loginActions'; interface Props { reduxIsLoggedIn: boolean; reduxLogin: Function; } const Routing = (props: Props) => { const { reduxIsLoggedIn, reduxLogin } = props; useEffect(() => { const checkAuth = async () => { try { const user = await getCurrentAuthUser(); if (!user) { reduxLogin(false); } } catch (error) {} }; checkAuth(); return () => {}; }, [reduxLogin]); return ( <NavigationContainer> {reduxIsLoggedIn ? <MainStack /> : <LoginStack />} </NavigationContainer> ); }; ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// const mapState = (state: any) => { return { reduxIsLoggedIn: state.stateLogin.isLoggedIn, }; }; const mapDispatch = (dispatch: Function) => { return { reduxLogin: (isLoggedIn: boolean) => dispatch(login(isLoggedIn)), }; }; export default connect(mapState, mapDispatch)(Routing);
For any nested level in redux persist you can now use this package.
https://github.com/PiotrKujawa/redux-deep-persist