书接上回《react 基础工程(react-redux & react-router)》,由于最近项目上的新实践新体验,所以记录一下。
依然,代码仓库:github。
一、用 @reduxjs/toolkit 创建 reducer 和 api
其实工程里已经用到这个工具,但是当时还没完全发现它的优势,还以为不过是官方推荐的比较好用的三方库而已。才知道确实简化了处理以及还有别的封装功能。
1、简化写法
以前老式的 redux 写法:
import { cloneDeep } from 'lodash';
export const addStringAction = payload => ({
type: 'ADD_STRING',
payload: payload,
});
export const minusStringAction = payload => ({
type: 'MINUS_STRING',
payload: payload,
});
const defaultState = {
b: 'abc',
};
export default function stringReducer(state = defaultState, action) {
const { type, payload } = action;
state = cloneDeep(state);
switch (type) {
case 'ADD_STRING':
state.b += payload;
return state;
case 'MINUS_STRING':
state.b = '';
return state;
default:
return state;
}
};
用 @reduxjs/toolkit 的写法:
import { createSlice } from '@reduxjs/toolkit';
export const counterSlice = createSlice({
name: 'counter',
initialState: {
value: 0,
},
reducers: {
increment: (state) => {
state.value += 1;
},
decrement: (state) => {
state.value -= 1;
},
incrementByAmount: (state, action) => {
state.value += action.payload;
},
},
});
export const { increment, decrement, incrementByAmount } = counterSlice.actions;
export default counterSlice.reducer;
a. 不需要再额外声明 action 了,不需要定义那些 type 了。reducers 字段下的每个方法就是个 action。用的时候直接
dispatch(increment(123))
即可。b. 而且好像可以直接改 state 上的字段,不需要返回一个完全新的 state 了?其实也是里面做了处理。看官方介绍,在注释里:
Redux Toolkit allows us to write “mutating” logic in reducers. It doesn’t actually mutate the state because it uses the Immer library, which detects changes to a “draft state” and produces a brand new immutable state based off those changes