说说你对@reduxjs/toolkit的理解?和react-redux有什么区别?
一、定义
React中使用react-redux
、@reduxjs/toolkit
状态管理工具
react-redux react
官方推出的redux
绑定库,react-redux
将所有组件分为两大类:UI组件
和容器组件
,其中所有容器组件包裹着UI组件,构成父子关系。容器组件负责和redux
交互,里面使用redux API
函数,UI组件负责页面渲染
- ,不使用任何
redux
API。容器组件会给UI组件传递redux
中保存对的状态和操作状态的方法 - @reduxjs/toolkit Redux 官方强烈推荐,开箱即用的一个高效的
Redux
开发工具集。它旨在成
- 为标准的
Redux
逻辑开发模式,使用Redux Toolkit
都可以优化你的代码,使其更可维护
二、使用
安装
在 create-react-app
应用中使用,此处使用版本:react v18.2.x、react-redux v8.0.x、
@reduxjs/toolkit v1.8.x
$ npm i react-redux @reduxjs/toolkit
根组件配置store
// 入口 src/index.js import React from 'react' import ReactDOM from 'react-dom/client' import App from './App' import store from './store' import { Provider } from 'react-redux' const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <Provider store={store}> <App /> </Provider> );
创建Reducer、Action
// src/store/dic.js import { createSlice } from '@reduxjs/toolkit' import baseApi from '../api/base' // 使用createSlice方法创建一个slice。每一个slice里面包含了reducer和actions,实现模块化的封装 export const counterSlice = createSlice({ // 命名空间 name: 'dic', // state数据的初始值 initialState: { sortList: [ { label: '食品类', value: '食品类' }, { label: '服装类', value: '服装类' }, { label: '日用品类', value: '日用品类' }, ] }, // 定义的action。由于内置了immutable插件,可以直接使用赋值的方式进行数据的改变 reducers: { changeVal: (state, action) => { // 第一个参数 state为当前state中的数据 // 第二个参数 action为 {payload: [{ label: '家具类', value: '家具类' }], type: "dic/changeVal"} // payload 为传过来的新参数值 // type 为action触发类型 console.log('changeVal:', JSON.parse(JSON.stringify(state)), state, action) state.sortList = action.payload } }, }) export const { changeVal } = counterSlice.actions export default counterSlice.reducer
创建store
// src/store/index.js import { configureStore } from '@reduxjs/toolkit' import dic from './dic' export default configureStore({ reducer: { dic, }, })
组件调用
// src/views/Goods.jsx import { useSelector, useDispatch } from 'react-redux' import { changeVal } from '@/store/dic' function Goods (props) { const dispatch = useDispatch() // 使用state中的数据 const sortList = useSelector((state) => state.dic.sortList) useEffect(() => { // 触发store中action以更新数据 dispatch(changeVal([{ label: '家具类', value: '家具类' }])) }, []) return ( <div> 渲染数据: <ul> { sortList.map(el => ( <li key={el.value}>{el.label}</li> )) } </ul> </div> ) } export default Goods
异步操作
方式1
// src/store/dic.js import { createSlice, createAsyncThunk } from '@reduxjs/toolkit' import baseApi from '../api/base' export const loadGoods = createAsyncThunk( 'dic/fetchGoods', (data, thunkAPI) => { // thunkAPI:一个对象,其中包含通常传递给 Redux thunk 函数的所有参数,以及其他选项(参考:https://redux-toolkit.js.org/api/createAsyncThunk#payloadcreator) baseApi.findGoods(data).then(res => { thunkAPI.dispatch(setGoods(res.result)) }) } ) export const counterSlice = createSlice({ name: 'dic', initialState: { goodsData: [], }, reducers: { setGoods: (state, action) => { state.goodsData = action.payload } }, }) export const { setGoods } = counterSlice.actions export default counterSlice.reducer
方式2
// src/store/dic.js import { createSlice, createAsyncThunk } from '@reduxjs/toolkit' import baseApi from '../api/base' export const loadGoods2 = createAsyncThunk( 'dic/fetchGoods2', (data, thunkAPI) => { return baseApi.findGoods(data).then(res => res.result) } ) export const counterSlice = createSlice({ name: 'dic', initialState: { goodsData: [], }, reducers: {}, extraReducers: { // 异步函数成功fulfilled时回调(类似的还有pending等待、rejected拒绝,此处只列举成功态) [loadGoods2.fulfilled](state, action) { state.goodsData = action.payload }, } }) // export const { } = counterSlice.actions export default counterSlice.reducer
组件调用
// src/views/Goods.jsx // 省略其它代码... useEffect(() => { dispatch(loadGoods({ name: '香蕉' })) dispatch(loadGoods2({ name: '橘子' })) }, []) // 省略其它代码...