Reputation: 4541
I'm trying to build a version of https://github.com/elgerlambert/redux-localstorage for React Native. The catch is that the React Native version of localStorage — AsyncStorage — has an asynchronous API. Unless I'm missing something, this effectively means that I cannot return the enhanced store with the existing store enhancer API.
Is there a workaround for this, or is it a fundamental problem in the store enhancer API?
Upvotes: 0
Views: 250
Reputation: 35970
Why is it important for the persistence operation to complete synchronously? I would argue that for performance reasons, you explicitly do not want the IO operation to delay the processing of the action within the Redux cycle.
Depending on your application, it might make sense to not only persist your store state asynchronously, but even debounce to persistence further to allow the user interaction and the following rerender to complete before persisting the new state.
Here is a simplified version of how I have implemented lazy persistence in my apps:
import {debounce} from 'lodash';
/**
* Redux middleware for persisting store state on change
*/
export default function takeStateSnapshot(store) {
// wait for input to stop for a while to avoid unnecessary
// serialization and IO overhead during busy dispatches
const takeLazySnapshot = debounce(saveSnapshot, 250);
return next => action => {
const result = next(action);
takeLazySnapshot(store.getState());
return result;
};
}
async function saveSnapshot(state) {
try {
await AsyncStorage.setItem('my-app-state', JSON.stringify(state));
} catch (e) {
console.error('Error persisting application state', e);
}
}
This approach does not give you guarantees that the latest state will be persisted in case of abrupt app shutdowns, but in our case it does not matter, as the store app state is used as a cache and never trusted as a source of truth.
Upvotes: 3