简体   繁体   中英

How to keep user logged in (Aka, state persistency) in react-native

I am trying to keep a user logged in in my application. I tried several techniques but i have no idea on how i can read data back into the state when the application launches.

Right now i have the following:

const getInitialState = () => {
    var _initState = {
        auth: new AuthInitialState(),
        global: (new GlobalInitialState())
    };

    return _initState;
};

export default function configureStore() {


    const store = createStoreWithMiddleware(reducer, load(APP_STORAGE) || getInitialState());

    store.subscribe(() => {
        if(!load('debug')) {
            save(APP_STORAGE, store.getState());
        }
    });

    return store;
};

const createStoreWithMiddleware = applyMiddleware(
    thunk,
    localStorageMiddleware,
    logger
)(createStore)

In which the load and save methods are responsible for saving data to an AsyncStorage (using react-native-simple-store)

export const load = (key) => {
    return store.get(key);
}

export const save = async (key, data) => {
    store.save(key, JSON.stringify(data));
}

The render of my root is the current:

render() {
    const store = configureStore();

    return (
        <Provider store={store}>
            <MyApp/>
        </Provider>
    );
}

The data is being correctly saved (through the save subscriber) but it is not correctly reloaded on a hot reload or app relaunch. Thus my user ends up being logged out every time.

In the end i would also like to apply this technique to navigate to the correct page upon app startup.

Any recommendations on how i can approach this?

You can use redux-persist to achieve this:

import { createStore, applyMiddleware, compose } from 'redux';
import { persistStore, autoRehydrate } from 'redux-persist';
import { AsyncStorage } from 'react-native';

export default function configureStore() {

   const store = createStore(reducers, getInitialState(), compose(
       applyMiddleware([
           thunk,
           localStorageMiddleware,
           logger
       ]),
       autoRehydrate()
      )
   );

   persistStore(store, { storage: AsyncStorage });

   return store;
};

With this, each time your application load, the store is hydrated from the local storage. You don't have to deal with the AsyncStorage , everything is done automatically for you. You can read the docs of redux-persist to customize it per your needs (add a whitelist , a blacklist , a callback when the store is rehydrated..)

Your basic approach looks good to me.

However, react-native-simple-store stringifies the state for you. As you run JSON.stringify() in your save function as well, it will not properly get decoded when it is loaded during the next start of your app.

See react-native-simple-store's codebase for more details.


To resolve this, remove JSON.stringify() from your save function :

export const save = async (key, data) => {
    store.save(key, data);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM