# 前言
在我们使用react中虽然可以借助useState 或者 useReducer 进行数据管理,但如果在多页面共享数据我们就需要借助props来传递数据,该方法虽然能解决问题但难免使页面变得复杂难以维护,因此出现了很多状态管理的库,其中最出名的当属redux,借助 state 和 dispatch 进行数据的维护。
# REACT常用状态管理库
- react-redux[(React Redux 中文文档 | React Redux 中文文档 (react-redux.js.org))](url)
- zustant [ZUSTAND 中文文档 | ZUSTAND (awesomedevin.github.io)](url)
- mobx [1. MobX 介绍 · MobX 中文文档](url)
# 如何选择?
react-redux 坐拥强大的社区深受全世界的喜爱,许多开发问题都可以在社区找到答案,缺点就是过于笨重,每个状态都需要配置state 和 reducer。
# 持久化配置库
yarn add @reduxjs/toolkit react-redux redux-persist
# 配置方式
store/user_slice.ts
"""
定义用户状态
"""
import {createSlice} from '@reduxjs/toolkit'
enum Gender {
male,
female,
other
}
interface UserState {
value: {
user_id: number,
username: string,
email: string,
full_name: string,
display_name: string,
avatar: string,
introduction: string,
gender: Gender.male | Gender.female | Gender.other,
birth_date: string,
user_role: string[]
}
}
const initialState: UserState = {
value: {
user_id: 0,
username: "",
email: "",
full_name: "",
display_name: "未登录用户",
avatar: "",
introduction: "",
gender: Gender.other,
birth_date: "",
user_role: []
}
}
export const userSlice = createSlice({
name: "user",
initialState,
reducers: {
login: (state, action) => {
return Object.assign({}, state, action.payload)
},
logout: (state) => {
state.value = initialState.value
},
},
})
export const {login, logout} = userSlice.actions
export default userSlice.reducer
store.ts
"use client";
import {combineReducers, configureStore} from '@reduxjs/toolkit'
import userReducer from "@/store/user_slice"
import {persistReducer} from 'redux-persist';
import createWebStorage from "redux-persist/lib/storage/createWebStorage";
const reducers = combineReducers({
user: userReducer
})
const createNoopStorage = () => {
return {
getItem(_key: any) {
return Promise.resolve(null);
},
setItem(_key: any, value: any) {
return Promise.resolve(value);
},
removeItem(_key: any) {
return Promise.resolve();
},
};
};
const storage =
typeof window !== "undefined"
? createWebStorage("local")
: createNoopStorage();
const persistConfig = {
key: 'root',
storage,
};
const persistedReducer = persistReducer(persistConfig, reducers);
export const makeStore = () => {
return configureStore({
reducer: persistedReducer,
devTools: process.env.NODE_ENV !== 'production',
})
}
// Infer the type of makeStore
export type AppStore = ReturnType<typeof makeStore>
// Infer the `RootState` and `AppDispatch` types from the store itself
export type RootState = ReturnType<AppStore['getState']>
export type AppDispatch = AppStore['dispatch']
hooks
import type {TypedUseSelectorHook} from 'react-redux'
import {useDispatch, useSelector, useStore} from 'react-redux'
import type {AppDispatch, AppStore, RootState} from './store'
// Use throughout your app instead of plain `useDispatch` and `useSelector`
export const useAppDispatch: () => AppDispatch = useDispatch
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector
export const useAppStore: () => AppStore = useStore
storeProvider
"use client"
import {ReactNode, useRef} from 'react'
import {Provider} from 'react-redux'
import {PersistGate} from 'redux-persist/integration/react';
import {AppStore, makeStore} from '@/lib/store'
import {persistStore} from 'redux-persist';
export default function StoreProvider({ children }: { children: ReactNode }) {
const storeRef = useRef<AppStore>()
const persistor = useRef<any>()
if (!storeRef.current) {
storeRef.current = makeStore()
persistor.current = persistStore(storeRef.current)
}
return (
<Provider store={storeRef.current}>
<PersistGate loading={null} persistor={persistor.current}>
{children}
</PersistGate>
</Provider>)
}
配置完毕后可以借助浏览器redux-devtools查看数据是否被缓存
import {
useAppDispatch,
useAppSelector
} from "hooks"
const user = useAppSelector((state) => state.user.value)
const dispatch = useAppDispatch()
除了使用redux 进行状态管理外如果希望全局共享的数据很少大家也可以借助 ahooks的 useLocalstorage 也是很好的方法。
ahooks [useUpdateLayoutEffect - ahooks 3.0](url)