Redux-persist: react-native asyncLocalStorage requires a global localStorage object

Created on 23 Sep 2016  路  6Comments  路  Source: rt2zz/redux-persist

Using react-native version 0.33.0

Getting he following error:

redux-persist asyncLocalStorage requires a global localStorage object. Either use a different storage backend or if this is a universal redux application you probably should conditionally persist like so: https://gist.github.com/rt2zz/ac9eb396793f95ff3c3b
import { createStore, applyMiddleware, compose, AsyncStorage } from 'redux';
import thunk from 'redux-thunk';
import createLogger from 'redux-logger';
import { persistStore, autoRehydrate } from 'redux-persist'

import { rootReducer } from '../redux';

const logger = createLogger({
  // Only log in dev mode
  predicate: (getState, action) => process.env.NODE_ENV === `development`
});

const enhancer = compose(
  applyMiddleware(thunk, logger),
  autoRehydrate()
);

export default function configureStore(initialState = {}) {
  const store = createStore(rootReducer, initialState, enhancer);
  persistStore(store, {storage: AsyncStorage});
  return store;
};

The ../redux index.js file is essentially:

export const rootReducer = combineReducers({
  auth,
  global,
...
});

Everything works if I remove the persistStore call to connect the rehydration to the store.

Most helpful comment

I think the AsyncStorage should be imported from react-native instead of redux. Try

import {AsyncStorage} from 'react-native'

All 6 comments

I think the AsyncStorage should be imported from react-native instead of redux. Try

import {AsyncStorage} from 'react-native'

Sigh. Thanks!

I am getting the same error even after importing AsyncStorage

 import React, {Component} from 'react'
 import { createStore, applyMiddleware } from 'redux'
 import { Provider } from 'react-redux'
 import thunk from 'redux-thunk'
 import {AsyncStorage} from 'react-native';
 import {persistStore, autoRehydrate} from 'redux-persist';
 import appReducers from './Reducers/CombineReducers'
 import AppContainerWithCardStack from './Containers/AppContainerWithCardStack';
 import Splash from './Splash';

  const createStoreWithMiddleware = applyMiddleware(thunk)(createStore);
  const store = createStore(appReducers, undefined, autoRehydrate());
  console.log('before persister store.getState():',store.getState());
  const persister=persistStore(store, {blacklist: ['navigationState'],storage: AsyncStorage});
  console.log('after persister store.getState():',store.getState());

  export default class App extends Component {
     constructor() {
        super()
        this.state = { rehydrated: false }
         }

      componentWillMount(){
        persistStore(store, {}, () => {
        this.setState({ rehydrated: true })
         });
  console.log('In componentWillMount:',this.state.rehydrated);
  console.log('after persister store.getState():',store.getState());
          }
      render() {
    if(!this.state.rehydrated)
    return <Splash />
    else
        return <Provider store={store} persister={persister}>
        <AppContainerWithCardStack />
           </Provider>

      }
        }

```

@Rashhh you need to pass the storage in to redux-persist:

      componentWillMount(){
        persistStore(store, {storage: AsyncStorage}, () => {
          this.setState({ rehydrated: true })
        });
      //...

you should not have to pass "this.setState" as an invoked function inside "persistStore"
you can run this.setState({ rehydrated: true }) outside like this:

componentWilllMount() { presistStore(store, { storage: AsyncStorage }); this.setState({ rehydrated: true }); }

it will not be rehydrated immediately as that is an async process, the callback on persistStore happens immediately after rehydration so is the ideal place for it.

Was this page helpful?
0 / 5 - 0 ratings