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 remendations on how i can approach this?
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 remendations on how i can approach this?
Share Improve this question edited Sep 19, 2016 at 23:57 Kerumen 4,3412 gold badges21 silver badges34 bronze badges asked Sep 19, 2016 at 19:59 MaximMaxim 3,9467 gold badges45 silver badges66 bronze badges2 Answers
Reset to default 12You can use redux-persist to achieve this:
import { createStore, applyMiddleware, pose } from 'redux';
import { persistStore, autoRehydrate } from 'redux-persist';
import { AsyncStorage } from 'react-native';
export default function configureStore() {
const store = createStore(reducers, getInitialState(), pose(
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);
}