Redux Toolkit
在认识redux-tookit 之前我们回顾一下react-redux
React-Redux
- 安装
npm i react react-redux -D
yarn add react react-redux -D
-
创建模板文件 types
-
创建 actions
- 创建 reducers
-
创建 store
-
将Redux连接到React
- 在React中使用
由于在UI组件中不能使用任何redux的api 所以有以下的两个方法
react-redux 7.1
之前我们通常使用 容器组件与ui组件整合的方法
import React, { useRef } from 'react'
//引入action
import {
decrement,
increment,
incrementAsync
} from '../../redux/actions/count'
//引入connect用于连接UI组件于redux
import { connect } from 'react-redux'
//组件
function Count(props) {
const selectNumber = useRef(null)
//加法
function increment (){
const {value} = selectNumber.current
props.increment(value*1)
}
//减法
function decrement (){
const {value} = selectNumber.current
props.decrement(value*1)
}
//奇数加法
function incrementIfOdd (){
const {value} = selectNumber.current
if(props.count%2 !==0){
props.increment(value*1)
}
}
//异步加法
function decrementAsync (){
const {value} = selectNumber.current
props.incrementAsync(value*1,500)
}
return (
<div>
<h1>我是Count组件,下面组件的人数{props.personCount.length}</h1>
<h3>当前求和为:{props.count}</h3>
<select ref={selectNumber}>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<br />
<button onClick={increment}>+</button>
<button onClick={decrement}>-</button>
<br />
<button onClick={incrementIfOdd}>当前求和为奇数再加</button>
<button onClick={decrementAsync}>异步加</button>
</div>
)
}
//调用connect函数 返回值接着调用 返回一个组件 并暴露这个组件
export default connect(
//映射状态
state => ({
count: state.count ,
personCount: state.persons
}),
//映射操作状态的方法
{
increment,
decrement,
incrementAsync
}
)(Count)
react-redux 7.1
之后
import React from 'react';
//引入action
import {
decrement,
increment,
incrementAsync
} from '../../redux/actions/count';
import { useDispatch, useSelector } from 'react-redux'
//组件
function Count() {
const selectNumber = useRef(null)
const count = useSelector(state => state.count)
const personCount = useSelector(state => state.persons)
const dispatch = useDispatch()
//加法
function increment() {
const { value } = selectNumber.current
dispatch(increment(value * 1))
}
//减法
function decrement() {
const { value } = selectNumber.current
dispatch(decrement(value * 1))
}
//奇数加法
function incrementIfOdd() {
const { value } = selectNumber.current
if (count % 2 !== 0) {
dispatch(increment(value * 1))
}
}
//异步加法
function decrementAsync() {
const { value } = selectNumber.current
dispatch(incrementAsync(value * 1, 500))
}
return (
<div>
<h1>我是Count组件,下面组件的人数{personCount.length}</h1>
<h3>当前求和为:{count}</h3>
<select ref={selectNumber}>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<br />
<button onClick={increment}>+</button>
<button onClick={decrement}>-</button>
<br />
<button onClick={incrementIfOdd}>当前求和为奇数再加</button>
<button onClick={decrementAsync}>异步加</button>
</div>
)
}
export default Count
Redux Toolkit
- 安装
npm install @reduxjs/toolkit react-redux
- 创建 slices
现在的slices
,就相当于以前的types、actions、reducers
,以对象的形式存在。
并且我们不用再返回新state
了,我们可以直接操作state
,它自己内部实现了immutable
的功能
// 引入 createSlice 用于创建 sclices
import { createSlice,createAsyncThunk } from '@reduxjs/toolkit';
// 创建初始值 objects
const objects= [
{
id: '001',
title: '测试第一',
flage:false
},
{
id: '002',
title: '测试第二',
flage:false
}, {
id: '003',
title: '测试第三',
flage:false
}
]
// 创建初始值 content
const content = [
]
//异步操作内容
export const conuntasync = createAsyncThunk(
"user/thunk",
async (payload:number) => {
//这里使用fetch请求
const res = await fetch(
`http://192.168.210.32:9527/api/goodlist?page=${payload}`
);
const response = await res.json();
return response;
}
)
const todo = createSlice({
//起一个名字 随便起,还是建议要有意义
name: 'todolice',
//与 之前 reducers 的第一参数一样 定义初始值 和 保存上一次的值
initialState: {
objects,
content
},
//定义方法 就是reducers的swicth case 内的操作
reducers: {
//每一个方法都有两个参数
//state 是 代理对象(Proxy)它的属性里有你定义的 对象 objects,content
//action 是 接收的值 就是你调用时传的值 后面会讲如何调用
add: (state, action) => {
if (action.payload.title === '') alert('内容不能为空')
else state.objects.push(action.payload)
},
remove: (state, action) => {
let arrs = state.objects.filter((item) => {
return item.id !== action.payload.id
})
state.objects = arrs
}
},
//这块内容不是很好理解 但是我平常只是使用它异步调用 仅此
//官方文档
//https://redux-toolkit.js.org/api/createSlice#the-extrareducers-builder-callback-notation
//把异步的执行过程写这里,是与store建立连接
extraReducers(builder){
builder
//conuntasync.pending 上面我们定义的 conuntasync的promise
//回调函数中第一个参数与reducers中一样,第二个值是异步得到的值
.addCase(conuntasync.pending, (state) => {
console.log("pending!")
})
.addCase(conuntasync.fulfilled, (state, {payload}) => {
console.log("fulfilled!", payload);
state.content = [...payload,...state.content]
})
.addCase(conuntasync.rejected, (state, err) => {
console.log("rejected!", err)
});
}
})
// 相当于以前的actions
export const { incremented, decremented, add } = todo.actions;
// 相当于以前的reducers
export default todo.reducer;
- 创建store
import { configureStore } from "@reduxjs/toolkit";
import counterSlice from "./slices/counterSlice";
const store = configureStore({
reducer: {
//这里用来汇总所有的slices name:value 类型
//value是 slices
//每一个slices 都要在这里建立一个 name:value 类型
todolice: todo
},
});
export default store;
- 将Redux连接到React
这里与react-redux一样
- 在React组件中使用
也是与react-redux 一样 不过建议使用 react-redux 内置hooks (useDispatch, useSelector)
使用useDispatch —> const dispatch = useDispatch()
使用useSelector —> 1. const objects = useSelector((state)=>{state.todolice.objects })
2.const content= useSelector((state)=>{state.todolice.content})
大概的后面的使用上面已经写过了
总结
react-redux的使用
- 安装
- 创建types
- 创建actions
- 创建reducers
- 创建store
- 将Redux连接到React
- 在React中使用
react toolkit的使用
- 安装
- 创建slices
- 创建store
- 将Redux连接到React
- 在React中使用
2-3步的文件创建流程
store
├── slices
│ ├── todo.js
│ └── ...
└── index.js -->store
Redux Toolkit
优点:
Redux Toolkit
已经集成了redux-devtools-extension
,不需要额外配置,非常方便。Redux Toolkit
已经集成了immutable-js
的功能,不需要我们额外安装配置使用,大大提升了开发效率。Redux Toolkit
已经集成了redux-thunk
的功能,不需要我们额外安装配置使用,大大提升了开发效率。Redux Toolkit
将types、actions、reducers
放在了一起组成全新的slices
一目了然简单易懂,简化了我们的使用。