[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
相关文章
- Mysql 的异常:The last packet successfully received from the server was 90 milliseconds ago. The last packet sent successfully to the server was 43,603,303 milliseconds ago. is longer than the server con
- Creating a new Signiant Transfer Engine because the previous transfer had to be canceled.
- [ubuntu]E: The package firmware-upgrade needs to be reinstalled, but I can't find an archive for it.
- [Typescript] Tips: Use 'extends' keyword to narrow the value of a generic
- [React] Use the useReducer Hook and Dispatch Actions to Update State (useReducer, useMemo, useEffect)
- [Redux] Adding React Router to the Project
- [Unit Testing for Zombie] Using Shoulda to clean up the code
- 解决 Jenkins 中无法展示 HTML 样式的问题,csp问题,Refused to apply inline style because it violates the following Content Security Policy directive: "style-src 'self'".
- [AWS Amplify] Deploy Your React Application to AWS Using the Amplify CLI
- [React Recoil] Write a Custom Recoil Hook to Reset a Value in the Recoil State
- [React] Use the useReducer Hook and Dispatch Actions to Update State (useReducer, useMemo, useEffect)
- [Javascript] Use a Pure RNG with the State ADT to Select an Element from State
- [MST] Create an Entry Form to Add Models to the State Tree
- association in CDS view is converted to LEFT OUTER MANY TO ONE JOIN in the runtime
- SAP Spartacus Enable the unit to allow editing 的信息提示框实现
- 成功解决MSB8020 The build tools for v141 (Platform Toolset = ‘v141‘) cannot be found. To build using the
- Docker“Got permission denied while trying to connect to the Docker daemon socket“问题
- Learn to securely share files on the blockchain with IPFS!
- `Warning: The default method for RunUMAP has changed from calling Python UMAP via reticulate to the
- 编译webrtc报错:ERROR: The installation of the Chrome OS default fonts failed.
- 【已解决最详细】failure: repodata/repomd.xml from base: [Errno 256] No more mirrors to try.服务器下载不了