react-toolkit最大的特点是:基于切片机制,把reducer和actionCreateor混在一起
官方强烈推荐的工具集,简化了redux很多文件及样板代码
安装
npm install @reduxjs/toolkit react-redux
redux-toolkit 需要借助 react-redux ,所以两个都需要安装
redux-toolkit的部分API
configureStore()
封装createStore以提供简化的配置选项和良好的默认值,默认包含redux-thunk
createSlice()
接受一个reducer函数对象、一个slice名称和一个初始状态值,并自动生成一个带有相应动作创建者和动作类型的slice reducer。
开发流程
用最简单的数据加减做例子,了解redux-toolkit的使用
1.store创建
在redux/react-redux使用时需要创建actions/ reducer等文件,在使用redux-toolkit是不需要创建这些
在使用redux-toolkit所需要创建的文件目录:
在features内创建不同模块的切片内容,在index.js内集成导出即可
store/index.js
import { configureStore } from '@reduxjs/toolkit'
import countSlice from './features/countSlice'
// configureStore创建一个redux数据
const store = configureStore({
// 按模块管理各个切片导出的reducer
reducer: {
count: countSlice,
},
})
export default store
这里的reducer是所有模块切片集合,统一配置
2.createSlice
使用createSlice方法创建一个slice。每一个slice里面包含了reducer和actions,可以实现模块化的封装。
所有的相关操作都独立在一个文件中完成。
切片内容:
import { createSlice } from '@reduxjs/toolkit'
export const countSlice = createSlice({
name: 'count',
initialState: { value: 0 },
reducers: {
add(state, { payload }) {
// 进行修改数据等操作
}
},
})
export const { add } = countSlice.actions
export default countSlice.reducer
这个是最简单的写法
createSlice内部属性:
- name 切片名称
- initialState 初始值
- reducers 内部的业务逻辑配置项
使用createSlice创建切片后,切片会自动根据配置对象生成action和reducer。action需要导出给调用处,调用处可以使用action作为dispatch的参数触发state的修改。reducer需要传递给configureStore以使其在仓库中生效。
全量代码:
import { createSlice } from '@reduxjs/toolkit'
const initialState = {
value: 0,
}
// 模拟异步方法
const delay = (interval = 1000) => {
return new Promise(resolve => {
setTimeout(() => {
resolve(Math.round(Math.random() * 10))
}, interval)
})
}
// 创建一个Slice
export const countSlice = createSlice({
// 设置切片名称
name: 'count',
// 初始状态
initialState,
// 编写不同业务逻辑下,对公共状态的更改
reducers: {
// 直接通过方法名称开发即可,不需要写switch case
add(state, { payload }) {
state.value += payload
},
sub(state) {
state.value -= 1
},
},
})
// 导出加减方法
export const { add, sub } = countSlice.actions
// 实现异步派发
export const addAsync = () => {
return async dispatch => {
let res = await delay()
dispatch(add(res));
};
};
console.log("countSlice.actions", countSlice);
// 导出 reducer
export default countSlice.reducer
配置完成,在index.js内使用
3.store传递
借助了react-redux 的 Provider src/index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
// antd汉化
import { ConfigProvider } from 'antd'
import zhCN from 'antd/locale/zh_CN';
// 页面内容
import Demo from './views/rtk-test';
import store from './store';
import { Provider } from 'react-redux';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<>
<ConfigProvider locale={zhCN}>
<Provider store={store}>
<Demo />
</Provider>
</ConfigProvider>
</>
);
4.组件使用
函数组件内,使用 useSelector 获取 store 内的数据,减少了storede 键入
使用 useDispatch 的原因,默认的dispatch对thunks不知道 所以需要 useDispatch 来进行派发,更符合RTK内的数据获取等操作
views/rtk-test.jsx
import React from 'react'
import { useDispatch, useSelector } from 'react-redux'
// 引入对应的方法
import { addAsync, sub } from '@/store/features/countSlice'
import { Button } from 'antd'
export default function Demo() {
const count = useSelector(state => state.count.value)
const dispatch = useDispatch()
return (
<div style={{ padding: '20px' }}>
<div>展示内容:{count}</div>
<div style={{ margin: "10px 0" }}>
<Button type="primary" onClick={() => {
dispatch(addAsync())
}} style={{ marginRight: "20px" }}>异步增加 0-10的随机数</Button>
<Button type="primary" onClick={() => dispatch(sub())}>减少 1</Button>
</div>
</div>
)
}
5.运行结果
这里的增加是 延迟 增加数据,可以在异步这里进行接口添加、数据获取等异步操作 减少 是同步,多种用法
对比下来,RTK将reducer和actionCreator结合起来,减少了代码量