sr3
sr3

Reputation: 399

React Native: storage only works in simulator

I've tried AsyncStorage, react-native-store, and react-native-simple-store, and they all work in the simulator, but not on a device. I'm using redux and redux-thunk to load the stored state. I call the following function in my root component's componentDidMount method (using react-native-simple-store):

export function loadState() {
  return (dispatch, getState) => {
    store.get('state').then((state) => {
      if (state) {
        let action = {
          type: LOAD_STATE,
          state: fromJS(state),
        };
        dispatch(action);
      } else {
        store.save('state', initialState);
      }
    }).catch((error) => {
      console.log(error);
    });
  };
}

And then in my reducer when the user triggers an update I'll update the state in storage before returning the new state like this:

case SET_UPDATED_DATE:
  newState = state.set('updatedDate', action.date);
  store.update('state', newState.toJS())
    .catch((error) => console.log(error));
  return newState;

Is the initializing/updating approach insufficient? Does something special need to be done to set it up for a device? Or is redux-thunk not supported when run on a device – main.jsbundle or with the development server – (putting a log statement at the top of the loadState function's returned function leads me to believe it may not be being called when on a device)?

Upvotes: 3

Views: 880

Answers (1)

sr3
sr3

Reputation: 399

Following the AsyncStorage docs' example, I've figured out a way to make it work. In my reducer file (my redux state is an Immutable.js object):

var STORAGE_KEY = '@AppName:state';

export function loadState() {
  return async (dispatch, getState) => {
    try {
      var value = await AsyncStorage.getItem(STORAGE_KEY);
      if (value !== null) {
        dispatch(replaceState(value));
        console.log('Recovered selection from disk:');
        console.log(value);
      } else {
        saveState(JSON.stringify(initialState.toJS()));
        console.log('No state on disk. Initialized with initialState.');
      }
    } catch (error) {
      console.log('AsyncStorage error: ' + error.message);
    }
  };
}

function replaceState(newState) {
  return {
    type: REPLACE_STATE,
    newState: fromJS(JSON.parse(newState)),
  };
}

async function saveState(state) {
  try {
    await AsyncStorage.setItem(STORAGE_KEY, state);
    console.log('Saved selection to disk:');
    console.log(state);
  } catch (error) {
    console.log('AsyncStorage error: ' + error.message);
  }
} 

Then in the reducer function:

case SET_UPDATED_DATE:
  newState = state.set('updatedDate', action.date);
  saveState(JSON.stringify(newState.toJS()));
  return newState;

Upvotes: 1

Related Questions