React的状态管理, Redux 早已家喻户晓,放到现在也算是 “古董” 般的存在,之后衍生的React-Redux虽便利了很多,但是单独来看也是代码量很多,并且涉及了HOC,很难让编码者理解。而随着React Hooks的引入,React编程思想早已进入新的阶段,为了迎合 “钩子”编程,Redux便出了Redux-toolkit(官方工具包,可npm安装),完全让Redux的代码可视化,更形象的切片(reducer)设计,与随拿随用的useSelector & useDispatch,让开发者爱不释手,而结合数据持久化工具Redux-Persist,更是React的最佳全家桶组合,本文便介绍了Redux-Persist结合Redux-toolkit的使用。
之前在网上查找的文档,多半是基于Redux使用Redux-Persist,Redux-toolkit & Redux-Persist的结合少之甚少,所以总结以下用法,方便同行交流、理解。
安装Redux-toolkit & Redux-Persist;
Redux的文件目录结构: src > redux > reportIdSlice.js && store.js;
store.js
// configureStore 简化了之前创建store的配置选项,可以内置多个reducer,并且配置redux-middleware,并且可在其中启用Redux Devtools扩展。
import { configureStore } from '@reduxjs/toolkit';
// 多个Slice的引入;
import numSlice from './reportIdSlice';
import stateSlice from './stateSlice';
import menu from './menu'
// persistStore 为redux-persist内置的状态管理仓库;
// persistReducer 为内置的切片管理;
import {persistStore, persistReducer} from 'redux-persist';
// storage redux-persist的思想是将要存储的数据通过storage存储在本地localstorage中;
import storage from 'redux-persist/lib/storage';
import autoMergeLevel2 from 'redux-persist/lib/stateReconciler/autoMergeLevel2';
// 配置要存储的Slice;
const persistConfig = {
key: 'root',
storage: storage,
stateReconciler: autoMergeLevel2
};
const myPersistReducer = persistReducer(persistConfig, numSlice)
export const store = configureStore({
// 通过configureStore可内置reducer & middleware
reducer: {
reportIdReducer: myPersistReducer,
access: stateSlice,
number: numSlice,
menu: menu
},
middleware: getDefaultMiddleware => {
return getDefaultMiddleware({
serializableCheck: false
});
},
})
export const persistor = persistStore(store)
// *** store对象 && 包裹store的persistStore都需导出,并在index.tsx中引入;
index.tsx
import { BrowserRouter } from "react-router-dom";
import ReactDOM from 'react-dom/client';
import App from './App';
import reportWebVitals from './reportWebVitals';
// 引入store;
import { store } from './redux/store';
// 需要通过Provider向下分发store;
import { Provider } from "react-redux";
import {persistor} from './redux/store';
// PersistGate的作用是向下分发persistStore对象;
import {PersistGate} from 'redux-persist/lib/integration/react';
// let _persistor = persistStore(store);
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
root.render(
<BrowserRouter>
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<App />
</PersistGate>
</Provider>
</BrowserRouter>
);
reportWebVitals();
以上就是Redux-Persist的配置代码;
reportIdSlice.js
import { createSlice } from '@reduxjs/toolkit'
const initialState = {
reportId: '',
}
export const reportIdSlice = createSlice({
name: 'setReportIdSlice',
initialState,
reducers: {
setReportId: (state, payload) => {
state.id = payload
},
},
})
export const { setReportId } = reportIdSlice.actions
export default reportIdSlice.reducer
A Page:
......
import { useDispatch } from 'react-redux';
import { setReportId } from '../../redux/reportIdSlice';
......
export default function A () {
......
const dispatch = useDispatch();
......
dispatch(setReportId(res.data.id))
}
B Page:
......
import { useSelector } from 'react-redux';
......
export default function B () {
......
const _reportId = useSelector(state => state.reportIdReducer.reportId.payload);
// 此时你会发现_reportId刷新后仍然存在;
// state中存在reportIdSlice的基础信息对象;
}