一、Redux Toolkit 概念了解
Redux Toolkit 是 Redux 官方强烈推荐,开箱即用的一个高效的 Redux 开发工具集。它旨在成为标准的 Redux 逻辑开发模式。
Redux Toolkit 最初是为了帮助解决有关 Redux 的三个常见问题而创建的:
"配置 Redux store 过于复杂"
"我必须添加很多软件包才能开始使用 Redux"
"Redux 有太多样板代码"
二、Redux Toolkit 使用
1、安装
cmd
# NPM
npm install @reduxjs/toolkit react-redux
# Yarn
yarn add @reduxjs/toolkit react-redux
2、创建 store
src/store/index.js
javascript
// 使用 RTK 来构建 store
import { configureStore } from '@reduxjs/toolkit'
import studentReducer from './slicers/studentSlice'
// 创建 store 用来创建store对象,需要一个配置对象作为参数
const store = configureStore({
// 用来配置 store 中用到的 reducer
reducer: {
student: studentReducer
}
})
export default store
3、根组件配置 store
入口 index.js 文件
javascript
import ReactDOM from 'react-dom/client'
import App from './App'
import { Provider } from 'react-redux'
import store from './store'
const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(
<Provider store={store}>
<App />
</Provider>
)
4、createSlice 创建 reducer 的切片
src/store/slicers/studentSlice.js
javascript
// 它需要一个配置对象作为参数,通过对象的不同的属性来指定它的配置
import { createSlice } from '@reduxjs/toolkit'
// state的初始值
const initialState = {
name: '莉莉',
info: {
sex: '男',
age: 18
}
}
export const studentSlice = createSlice({
name: 'stu', // 命名空间,用来自动生成action中的type,name值会成为前缀;保证唯一,不重名
initialState,
reducers: { // 指定state的各种操作,直接在对象中添加方法
// 可以通过不同的方法来指定对state的不同操作
// 两个参数:state代理对象,可以直接修改;action操作的信息
setName(state, action) {
state.name = action.payload
},
setInfo(state, action) {
state.info = action.payload
}
}
})
// 切片对象会【自动】的帮助我们生成action;切片对象存在属性actions
// actions中存储的是slice自动生成action创建器(函数),调用函数后会自动创建action对象
// action对象的结构 {type:name/函数名, payload:函数的参数}
export const { setName, setInfo } = studentSlice.actions
// const nameAction = setName('哈哈') // { type: 'stu/setName', payload: '哈哈'}
// const infoAction = setInfo({sex:'女',age:18}) // { type: 'stu/setInfo', payload: {sex:'女',age:18}}
// 简化useSelector使用,student来源于store里面配置的reducer
export const selectName = state => state.student.name
export const selectInfo = state => state.student.info
// 导出reducer在store里面使用
export default studentSlice.reducer
5、页面使用
useDispatch() 用来获取派发器对象
useSelector() 用来加载 state 中的数据
javascript
import React from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { setName, setInfo, selectName, selectInfo } from './store/slicers/studentSlice'
const App = () => {
// 获取student中的name值
// const name = useSelector(state => state.student.name)
// 简化写法
const name = useSelector(selectName)
const info = useSelector(selectInfo)
const dispatch = useDispatch()
const setNameHandler = () => {
dispatch(setName('哈哈'))
}
const setInfoHandler = () => {
dispatch(setInfo({sex: '女', age: 18}))
}
return (
<div>
<p>
{name} ---
{info.sex} ---
{info.age} ---
</p>
<button onClick={setNameHandler}>修改name</button>
<button onClick={setInfoHandler}>修改info</button>
</div>
)
}
export default App
三、redux-persist 持久化储存
在实际开发中,如果用户刷新了网页,那么我们通过 redux 存储的全局数据就会丢失,比如登录信息。可以通过 localStorage 将信息存储到本地,需要自己添加逻辑(了解)。
通过 redux-persist 实现持久化储存,使用过程:
1、 安装
cmd
npm install redux-persist
2、配置 store
javascript
import { configureStore } from '@reduxjs/toolkit'
import { combineReducers } from 'redux'
// 配置数据的持久化效果
import { persistStore, persistReducer} from 'redux-persist'
// 导入需要配置的数据源,可选storage、cookie、session等
import storage from 'redux-persist/lib/storage'
// import storageSession from 'redux-persist/lib/storage/session'
import userReducer from '@/store/slicers/userSlice'
import menuReducer from '@/store/slicers/menuSlice'
// 合并多个模块
const reducers = combineReducers({
user: userReducer,
menu: menuReducer
})
// 配置持久化设置
const persistConfig = {
key: 'root',
storage, // 持久化存储引擎
// 可选的配置项,如白名单、黑名单等 选其一
// blacklist: ['不想缓存的状态的名字'],
// whitelist: ['想要缓存状态的名字']
}
// 创建持久化的配置persist的信息
const persistedReducer = persistReducer(persistConfig, reducers)
// 创建存储对象并且抛出对象
export const store = configureStore({
reducer: persistedReducer
})
// 使用persistStore包裹并抛出
export const persistor = persistStore(store)
3、index.js入口文件中配置
在入口文件中使用 PersistGate 包裹根组件,这将延迟渲染 app 视图直到持久化状态取回并保存到 redux 中。
将 store 提供给应用程序,persistor对象提供给根组件
javascript
import ReactDOM from 'react-dom/client'
import App from './App'
import { Provider } from 'react-redux'
// 导入redux中对应抛出的store对象和persistor对象
import { store, persistor } from '@/store'
// 如果使用React,则使用 PersistGate 包裹根组建
import { PersistGate } from 'redux-persist/lib/integration/react'
const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<App />
</PersistGate>
</Provider>
)