In this tutorial, you’ll learn how to implement Redux Persist to save your Redux state to AsyncStorage, ensuring that your app’s data remains accessible offline. By the end of today’s lesson, your app will retain important state data, such as authentication tokens or user preferences, even after the app restarts.
What You Will Learn Today:
- Setting up Redux Persist with AsyncStorage
- Persisting the Redux store for offline access
- Configuring persisted state for specific reducers
- Testing offline data persistence
Step 1: Installing Redux Persist
Redux Persist integrates with Redux and allows you to persist (or save) the Redux state to storage so that it remains available even after the app restarts.
- Install redux-persist and @react-native-async-storage/async-storage:
npm install redux-persist @react-native-async-storage/async-storage
Explanation:
- redux-persist: This library lets you automatically save and rehydrate (reload) your Redux state from storage.
- @react-native-async-storage/async-storage: Provides an asynchronous, persistent key-value storage system that’s ideal for React Native.
Step 2: Configuring Redux Persist with AsyncStorage
To enable Redux Persist in your app, you need to configure the Redux store to use persistence.
- Open
store/store.js
and update it to configure Redux Persist:
import { createStore, applyMiddleware } from 'redux';
import { persistStore, persistReducer } from 'redux-persist';
import AsyncStorage from '@react-native-async-storage/async-storage';
import createSagaMiddleware from 'redux-saga';
import rootReducer from './reducers';
import rootSaga from './sagas';
const sagaMiddleware = createSagaMiddleware();
// Configure Redux Persist
const persistConfig = {
key: 'root',
storage: AsyncStorage,
whitelist: ['auth'], // Only persist the 'auth' reducer (you can add more if needed)
};
const persistedReducer = persistReducer(persistConfig, rootReducer);
const store = createStore(persistedReducer, applyMiddleware(sagaMiddleware));
const persistor = persistStore(store);
sagaMiddleware.run(rootSaga);
export { store, persistor };
Explanation:
- persistConfig: This configuration object specifies how Redux Persist should work. The
key
property is a unique identifier for the persisted state,storage
is set toAsyncStorage
, andwhitelist
specifies which reducers should be persisted (e.g.,auth
for authentication data). - persistReducer: Enhances the root reducer with persistence capabilities.
- persistStore: Initializes Redux Persist and sets up the persistor for your Redux store.
Step 3: Wrapping the App in PersistGate
To use Redux Persist, you’ll need to wrap your app’s main component in PersistGate, which delays the rendering of your app until the persisted state is rehydrated.
- Open
App.js
and modify it as follows:
import React from 'react';
import { Provider } from 'react-redux';
import { PersistGate } from 'redux-persist/integration/react';
import { store, persistor } from './store/store';
import LoginScreen from './LoginScreen';
import HomeScreen from './HomeScreen';
function AppContent() {
const token = useSelector((state) => state.auth.token);
return token ? <HomeScreen /> : <LoginScreen />;
}
export default function App() {
return (
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<AppContent />
</PersistGate>
</Provider>
);
}
Explanation:
- PersistGate: Suspends the rendering of your app until the persisted Redux state is loaded from AsyncStorage.
- loading: You can pass a loading component here (e.g., a spinner) to show while the persisted state is being rehydrated.
Step 4: Persisting Specific Reducers
You can control which parts of the Redux state are persisted by adding reducers to the whitelist
in the persist configuration. Here, we’ve whitelisted only the auth
reducer, so only authentication-related data is saved and loaded.
- Open
store/store.js
(already configured above), and ensurewhitelist: ['auth']
includes any reducers you want to persist. - For instance, if you want to persist both
auth
andposts
, you could write:
whitelist: ['auth', 'posts']
Step 5: Testing Offline Data Persistence
Let’s now test whether data persists correctly by logging in, restarting the app, and seeing if the authentication state is retained.
- Run your app:
npm start
- Log in using the LoginScreen. Once logged in, you should be redirected to the HomeScreen.
- Close and restart the app to simulate a fresh start.
- If the login token is persisted correctly, you should see the HomeScreen instead of the LoginScreen upon reopening the app.
Optional: Adding Auto-Rehydrate
To make sure that the app loads as quickly as possible, you can enable auto-rehydration. Redux Persist handles rehydration out of the box with PersistGate, but if you want instant access to specific state portions, consider using autoRehydrate
.
Step 6: Recap and Summary
In today’s tutorial, you learned how to implement offline data storage with Redux Persist and AsyncStorage in a React Native app. Here’s a quick summary of what you’ve done:
- Installed redux-persist and @react-native-async-storage/async-storage.
- Configured Redux Persist with AsyncStorage to save and reload Redux state automatically.
- Wrapped your app in PersistGate to manage the rehydration process.
- Specified which reducers to persist, controlling which parts of the state are stored offline.
- Tested the offline persistence by logging in, restarting the app, and verifying the authentication state.
With offline persistence in place, your app can retain important data even after restarting, providing a seamless user experience.
Next Up: Day 7 – Integrating Push Notifications with Firebase Cloud Messaging
In Day 7, we’ll explore integrating push notifications using Firebase Cloud Messaging (FCM), enabling your app to send and receive notifications even when it’s closed or running in the background.
Stay tuned for more advanced features tomorrow!