react + redux + react-redux + redux-persist
注:
1、react-redux
这里我有文章介绍:文章链接
2、如果是使用 redux-toolkit
,请看这篇文章链接
我这里结合redux的例子 todos 来的
npm i redux-persist
官方文档:文档链接
注:有接触过 react-redux 的,看 2.1、2.2 就行
src/store/index.js
import { createStore } from 'redux'
import { persistStore, persistReducer } from 'redux-persist'
import storage from 'redux-persist/lib/storage';
import rootReducer from '../reducers'
// 配置对象
const persistConfig = {
key: 'root',
storage,
}
// 创建一个新的 Redux 状态 reducer
const persistedReducer = persistReducer(persistConfig, rootReducer)
let store = createStore(persistedReducer)
// 创建一个新的 Redux store
let persistor = persistStore(store)
const storePersistor = { store, persistor }
export default storePersistor;
src/index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import { Provider } from 'react-redux'
import { PersistGate } from 'redux-persist/integration/react';
import storePersistor from './store';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<Provider store={storePersistor.store}>
{/* 使用 PersistGate 包装根组件,这会延迟应用 UI 的呈现,直到检索到持久化状态并将其保存到 redux 中 */}
<PersistGate loading={null} persistor={storePersistor.persistor}>
<App />
</PersistGate>
</ Provider>
);
src/App.js
import React from "react";
import AddTodo from "./containers/AddTodo";
import VisibleTodoList from "./containers/VisibleTodoList";
function App() {
return (
<div className="App">
<AddTodo />
<VisibleTodoList />
</div>
);
}
export default App;
src/actions/index.js
export const addTodo = (text) => {
return {
type: 'ADD_TODO',
id: new Date().getTime(),
text,
}
}
src/reducers/index.js
import { combineReducers } from 'redux'
import todos from './todos'
const todoApp = combineReducers({
todos,
})
export default todoApp;
src/reducers/todos.js
const todos = (state = [], action) => {
switch (action.type) {
case 'ADD_TODO':
return [
...state,
{
id: action.id,
text: action.text
}
]
default:
return state
}
}
export default todos;
/src/containers/AddTodo.js
import React, { createRef } from "react";
import { connect } from "react-redux"
import { addTodo } from '../actions/index'
const AddTodo = ({dispatch}) => {
const inp = createRef()
const add = () => {
const val = inp.current.value;
console.log('添加', val);
dispatch(addTodo(val))
}
return (
<div>
<input ref={inp} />
<button onClick={add}>Add Todo</button>
</div>
)
}
export default connect()(AddTodo);
src/containers/VisibleTodoList.js
import { connect } from 'react-redux';
import TodoList from '../components/TodoList';
const mapStateToProps = (state) => {
return {
todos: state.todos,
}
}
const mapDispatchToProps = (dispatch) => {
return {
}
}
const VisibleTodoList = connect(mapStateToProps, mapDispatchToProps)(TodoList);
export default VisibleTodoList;
src/components/TodoList.js
import React from "react";
const TodoList = ({ todos }) => {
return (
<div>
{
todos.map((todo, index) => {
return <li key={todo.id}>{todo.id}--{todo.text}</li>
})
}
</div>
)
}
export default TodoList;
状态协调器定义如何将传入状态与初始状态合并
选项的作用是强制将本地存储的值设置为 Redux 状态,而不是尝试合并它们,这可以确保在加载状态时,本地存储的值始终与 Redux 状态相匹配
举例说明:
传入状态: { foo: incomingFoo }
初始状态: { foo: initialFoo, bar: initialBar }
最终状态: { foo: incomingFoo } // 最终为传入的状态
import hardSet from 'redux-persist/lib/stateReconciler/hardSet'
const persistConfig = {
key: 'root',
storage,
stateReconciler: hardSet,
}
这将自动合并一级深度。
举例:
传入状态: { foo: incomingFoo }
初始状态: { foo: initialFoo, bar: initialBar }
最终状态: { foo: incomingFoo, bar: initialBar } // 注意 incomingFoo 覆盖 initialFoo
这与 autoMergeLevel1 类似,只不过它浅层合并了两个级别
举例说明:
传入状态: { foo: incomingFoo }
初始状态: { foo: initialFoo, bar: initialBar }
最终状态:{ foo: mergedFoo, bar: initialBar } // 注意: { foo: mergedFoo, bar: initialBar } initialFoo 和 incomingFoo 是浅层合并的
这里就用官方的例子:
// BLACKLIST
const persistConfig = {
key: 'root',
storage: storage,
blacklist: ['navigation'] // navigation will not be persisted
};
// WHITELIST
const persistConfig = {
key: 'root',
storage: storage,
whitelist: ['navigation'] // only navigation will be persisted
};
嵌套持久性可用于包含不同的存储适配器、代码拆分或深度筛选。例如,虽然黑名单和白名单只工作一个级别的深度,但我们可以使用嵌套的持久化来黑名单更深的值:
import { combineReducers } from 'redux'
import { persistReducer } from 'redux-persist'
import storage from 'redux-persist/lib/storage'
import { authReducer, otherReducer } from './reducers'
const rootPersistConfig = {
key: 'root',
storage: storage,
blacklist: ['auth']
}
const authPersistConfig = {
key: 'auth',
storage: storage,
blacklist: ['somethingTemporary']
}
const rootReducer = combineReducers({
auth: persistReducer(authPersistConfig, authReducer),
other: otherReducer,
})
export default persistReducer(rootPersistConfig, rootReducer)
localStorage
import storage from 'redux-persist/lib/storage'
sessionStorage
import storageSession from 'redux-persist/lib/storage/session'