Reputation: 1498
I am using redux-persist to store the data in my react-native app. This is the code:
store.js
import { createStore, compose, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import {
persistStore,
persistCombineReducers,
} from 'redux-persist';
import { AsyncStorage } from 'react-native';
import { composeWithDevTools } from 'redux-devtools-extension';
import user from './reducers/user';
import auth from './reducers/auth';
const config = {
key: 'root',
storage: AsyncStorage,
};
const reducers = persistCombineReducers(config, {
user,
auth
});
export const configureStore = () => {
const store = createStore(
reducers,
compose(
applyMiddleware(thunk),
)
);
const persistor = persistStore(store);
return { persistor, store };
};
Then in the App.js I have this :
const { persistor, store } = configureStore();
const onBeforeLift = () => {
// take some action before the gate lifts
store.dispatch(startingApp());
}
return (
<Provider store={store}>
<PersistGate
loading={<HomeLoader />}
onBeforeLift={onBeforeLift}
persistor={persistor}>
<RootNav />
</PersistGate>
</Provider>
Everything works fine when I dispatch and action from the App.js componentDidMount. The problem is that when I fire the action from component, for example, the state is not stored, so when I restart the app the state is gone.
What I do in is just calling the action and passing the data:
this.props.onSetAuthData(data.credentials);
The state is updated as I can see in the console, but if I restart the app, only the state created by the action in App.js is saved, not the one in
Maybe this has to do with the RootNav component ?
maybe I am exporting wrong the reducers? I have const user = (state = initialState, action = {}) => {} export default user. Same for the other reducer: const auth = (state = initialState, action = {}) => {} export default auth.
Then I export with combineReducers({auth, user})
Is this wrong?
Upvotes: 4
Views: 5869
Reputation: 1
In my case it was actually a problem with the AsyncStorage library itself(also see this issue).
I ended up writing my own Nativemodule with getItem, setItem, and removeItem etc methods, after which it worked seamlessly.
I added more details on my friend's blog here
Hope it helps someone.
Upvotes: 0
Reputation: 2019
sometimes it calls an error with the key in persistConfig. try key: 'primary'
const primary = {
key: 'root',
storage: AsyncStorage,
blacklist: [],
whitelist: ['user'],
};
Upvotes: 0
Reputation: 1122
Use tool like Reacttotron to see if your store is persisted or not.
https://github.com/infinitered/reactotron
If it's already persisted your component should wait until the store rehydrated on app launch. Sometimes I can't use the redux persist using persistgate
to wait for the persisted store to be rehydrated. So I set the store and persistor into state on async componentWillMount
then in your render, check if the store is not empty (null) and already rehydrated then load your app.
constructor(){
super();
this.state = {store: null, persistor: null}
}
async componentWillMount () {
const store = configureStore();
this.setState({ store: store.store })
this.setState({ persistor: store.persistor })
}
render(){
return (
if (this.state.store === null) {
return (
<View>
<Text>Loading...</Text>
</View>
);
}
<Provider store={this.state.store} persistor={this.state.persistor}>
<RootNav />
</Provider>
Also try to change your storage from AsyncStorage
to storage
.
const config = {
key: 'root',
storage,
};
First import the storage import storage from 'redux-persist/es/storage';
Upvotes: 2