Redux Toolkit的使用
1.使用推荐命令创建项目:
npx create-react-app AppName --template redux
2.分析项目代码:
2.1 store.js
import { configureStore } from '@reduxjs/toolkit';//可以融合多个reducer,并集成了redux-thunk,Redux DevTools
import counterReducer from '../features/counter/counterSlice';
export const store = configureStore({
reducer: {
counter: counterReducer,
},
});
对比旧版本代码:
import { createStore, applyMiddleWar, combineReducers} from 'redux';
import thunk from 'redux-thunk';
const reducers = combineReducers({counter:counterReducer});
const store = createStore(reducers,{}, applyMiddleWar, thunk));
2.2 counterSlice文件:
import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';
import { fetchCount } from './counterAPI';
// 初始化的数据
const initialState = {
value: 0,
status: 'idle',
};
// 异步请求的方法
export const incrementAsync = createAsyncThunk(
'counter/fetchCount',//请求的接口地址
async (amount) => { //amount 为请求的参数
const response = await fetchCount(amount);//接收请求的响应数据
// 这个返回值,将会在 fulfilled 成功状态的 action.payload 中获取
return response.data;
}
);
// 创建slice(片段)-- 集成了createReducer,createAction(@reduxjs/toolkit中的方法)
export const counterSlice = createSlice({
name: 'counter', //slice的名字
initialState, //初始化数据
// 定义reducers
reducers: {
increment: (state) => {
// 集成了Immer库,它检测到“draft state"”的更改并生成一个全新的
state.value += 1;
},
decrement: (state, action) => {
state.value -= 1;
},
//调用方法传入的参数都在action.payload属性中
incrementByAmount: (state, action) => {
state.value += action.payload;
},
},
// 额外的reducer,用来处理异步请求方法
extraReducers: (builder) => {
builder
.addCase(incrementAsync.pending, (state) => {//pending请求过程中
state.status = 'loading';//设置loading
})
.addCase(incrementAsync.fulfilled, (state, action) => {//fulfilled请求完成
state.status = 'idle';//取消loading
state.value += action.payload;//将请求的响应数据设置到slice中
//action.payload就是上面incrementAsync方法return出来的响应数据
})
.addCase(incrementAsync.rejected, (state, action) => {
//rejected请求拒绝
});
},
});
// 将action方法暴露出去
export const { increment, decrement, incrementByAmount } = counterSlice.actions;
// 可以选择一个值暴露出去,使用方法:import {selectCount} from './counterSlice'; const counter = useSelector(selectCount);
// 也可以在文件中直接采用:const counter = useSelector((state: RootState) => state.counter.value)
export const selectCount = (state) => state.counter.value;
//我们也可以手工编写thunk,它可能包含同步和异步逻辑。
//下面是一个基于当前状态有条件地分派操作的示例。
export const incrementIfOdd = (amount) => (dispatch, getState) => {
// amount是调用方法传入的参数
// getState()方法可以获取到项目中store中所有的reducer数据
// selectCount(getState()) 获取到的是当前slice中的value数据
const currentValue = selectCount(getState());
if (currentValue % 2 === 1) {
// 当前值如果为基数的话执行下面的函数 这里调用了slice中的其他方法
dispatch(incrementByAmount(amount));
}
};
// 把当前创建的reducer暴露出去(必不可少)
export default counterSlice.reducer;
3.看看slice中的方法和数据都是怎么使用的:
import { useSelector, useDispatch } from 'react-redux';
import {
decrement,
increment,
incrementByAmount,
incrementAsync,
incrementIfOdd,
selectCount,
} from './counterSlice';
const count = useSelector(selectCount);//获取到的是slice中的value数据
// 等同于 === 》 const counter = useSelector((state) => state.counter.value)
//const { value, status } = useSelector(state => state.counter) 可以一次解构多个数据
const dispatch = useDispatch();
<button onClick={() => dispatch(decrement())}> - <button>//调用方法
<button onClick={() => dispatch(incrementByAmount(incrementValue))}> Add Amount <button>
<button onClick={() => dispatch(incrementIfOdd(incrementValue))}> Add If Odd <button>
4.处理thunk的返回结果:
4.1直接在请求方法中进行
export const fetchCustomer = createAsyncThunk( `${namespaces}/fetchCustomer`, async (params: ParamsTypes, { dispatch }) => { const { changeLoading } = customerSlice.actions; dispatch(changeLoading(true)); const res = await server.fetchCustomer(params); dispatch(changeLoading(false)); if (res.status === 0) { return res.data; } else { message.error(res.message); } }, );
4.2 使用try...catch
const updateUser = createAsyncThunk( 'users/update', async (userData, { rejectWithValue }) => { const { id, ...fields } = userData try { const response = await userAPI.updateById(id, fields) return response.data.user } catch (err) { // Use `err.response.data` as `action.payload` for a `rejected` action, // by explicitly returning it using the `rejectWithValue()` utility return rejectWithValue(err.response.data) } } )
官方中文文档:http://cn.redux.js.org/redux-toolkit/overview
参考地址:
https://blog.csdn.net/ilovethesunshine/article/details/109627560
https://blog.csdn.net/dfsgwe1231/article/details/107258846
https://www.jianshu.com/p/3f4e6fef4d89
https://blog.csdn.net/pig_fu/article/details/113870074

浙公网安备 33010602011771号