您的位置:首页 > 其它

[Redux] Persisting the State to the Local Storage

2016-06-04 03:43 459 查看
We will learn how to use store.subscribe() to efficiently persist some of the app’s state to localStorage and restore it after a refresh.

To save data in to localStroge, we first create a localStorgejs file and two methods, one for get and one for set:

export const loadState =  () => {
// Important to use try catch for localStorage if browser doesn't support local storge
try{
const serializedState = localStorage.getItem('state');
if(serializedState === null){
// if there is no item stored, then use default ES6 param
return undefined;
}else{
return JSON.parse(serializedState)
}
}catch(err){
return undefined;
}
}

export const saveState = (state) => {
try{
const serializedState = JSON.stringify(state);
localStorage.setItem('state', serializedState);
}catch(err){
console.error("Cannot save to storage");
}
}


The data we want to save into localStorage should be serializable. And should use try and catch to handle error.

Use loadState() to get presisted data and to create store:

const persistedState = loadState();
const store = createStore(todoApp, persistedState);


Subscribe to the store, everytime there is something changed, save the todos into localStorge:

store.subscribe( () => {
const {todos} = store.getState();
saveState({
todos
})
})


If already save some todos into the localStroge and refresh the app, then we find that we cannot save any todo anymore. this is because in the application we use 'nextTodoId':

let nextTodoId = 0;
export const addTodo = (text) => ({
type: 'ADD_TODO',
id: (nextTodoId++).toString(),
text,
});


Everytime page refresh it will start from zero again, then it cause the problem.

Install:

npm i --save node-uuid


node-uuid has a method call v4() to generate a random id:

// Generate a v4 (random) id
uuid.v4(); // -> '110ec58a-a0f2-4ac4-8393-c866d813b8d1'


We can use it to replace the old implemention:

import {v4} from 'node-uuid';

export const addTodo = (text) => ({
type: 'ADD_TODO',
id: v4(),
text,
});


One thing to be improved is everytime we update the stroe, saveState() function will be invoked. We want to add throttle to it:

Install:

npm i --save lodash


import throttle from 'lodash/throttle';

const persistedState = loadState(); const store = createStore(todoApp, persistedState);

store.subscribe( throttle(() => {
const {todos} = store.getState();
saveState({
todos
})
}, 1000));


------------------------------

If look at the tests for createStore(), the second args can accpet 'undefined', [], {}, fn but NOT null. So it is important to return 'undefined' let reducer accept the ES6 default param.

See Link: https://github.com/reactjs/redux/blob/master/test/createStore.spec.js#L546
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: