[Redux] Persisting the State to the Local Storage

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

 

posted @   Zhentiw  阅读(404)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
历史上的今天:
2015-06-04 [D3] 11. Basic D3 chart interactivity on(), select(this), classed(class, trueorfalse)
2015-06-04 [D3] 10. Creating Axes with D3
2015-06-04 [D3] 9. Scatter Plot
2015-06-04 [D3] 8. Margins
2015-06-04 [D3] 7. Quantitative Scales
点击右上角即可分享
微信分享提示