react-redux的现代化用法 - 拥抱@reduxjs/toolkit
全栈老韩
全栈工程师,擅长iOS App开发、前端(vue、react、nuxt、小程序&Taro)开发、Flutter、React Native、后端(midwayjs、golang、express、koa)开发、docker容器、seo优化等。
首先我们来介绍一下这篇文章的主角:@reduxjs/toolkit,一个全新的react redux集合。
@reduxjs/toolkit诞生的原因,在官网(https://redux-toolkit.js.org/introduction/getting-started)上给出了明确的说法:
"Configuring a Redux store is too complicated"
"I have to add a lot of packages to get Redux to do anything useful"
"Redux requires too much boilerplate code"
简单的说,就是原来的react redux写法太复杂,并且需要添加更多的npm包去实现redux的逻辑,而且老版本中有一堆的模版代码写法。
那么新的@reduxjs/toolkit和旧的比,有哪些新颖写法,这篇文章对通用的几个写法做了一些对比。
对比
- 老写法
需要依赖:
package.json
...
"redux-logger": "^3.0.6",
"redux-thunk": "^2.3.0",
"redux": "^4.0.0",
"react-redux": "^7.2.0",
...
- store创建
store.ts
import { legacy_createStore as createStore, applyMiddleware, compose } from 'redux'
import thunkMiddleware from 'redux-thunk'
import logger from 'redux-logger'
import rootReducer from '../reducers'
const composeEnhancers = typeof window === 'object' && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({
// Specify extension’s options like name, actionsBlacklist, actionsCreators, serialize...
})
: compose
const middlewares = [
thunkMiddleware
]
if (process.env.NODE_ENV === 'development') {
middlewares.push(logger)
}
const enhancer = composeEnhancers(
applyMiddleware(...middlewares),
// other store enhancers if any
)
export default function configStore () {
const store = createStore(rootReducer, enhancer)
return store
}
- reducer集合
rootReducer.ts
import { combineReducers } from 'redux'
import counter from './counter'
export default combineReducers({
counter
})
- 声明方法case
constants/counter.ts
export const ADD = 'ADD'
export const MINUS = 'MINUS'
- 声明action方法
actions/counter.ts
import {
ADD,
MINUS
} from '../constants/counter'
export const add = () => {
return {
type: ADD
}
}
export const minus = () => {
return {
type: MINUS
}
}
// 异步的action
export function asyncAdd () {
return dispatch => {
setTimeout(() => {
dispatch(add())
}, 2000)
}
}
- 具体的某一个reducer
counter.ts
import { ADD, MINUS } from "../constants/counter";
const INITIAL_STATE = {
num: 0,
};
export default function counter(state = INITIAL_STATE, action) {
switch (action.type) {
case ADD:
return {
...state,
num: state.num + 1,
};
case MINUS:
return {
...state,
num: state.num - 1,
};
default:
return state;
}
}
- 调用reducer
index.tsx
...
// 第一种,component组件,如果你要将reducer绑定为组件的属性使用,那么要使用connect函数
export default connect(({ counter }) => ({
counter
}), (dispatch) => ({
add () {
dispatch(add())
},
dec () {
dispatch(minus())
},
asyncAdd () {
dispatch(asyncAdd())
}
}), IndexComponent) // IndexComponent是你的组件
// 然后通过this.props去读取属性或者调用方法
// 第二种,如果你要使用函数式组件,那么可以使用useSelector和useDispatch去使用
const dispatch = useDispatch();
dispatch(add())
...
从上面老的写法中,我们可以看出,在声明、使用redux的过程中,存在着很多繁琐的步骤。比如你需要创建一个新的reducer,那么上面counter的写法,你都得来一遍,每一个步骤又臭又长,把一个读写的逻辑搞的太过于复杂,模版代码就如counter的reducer文件中一样。
- 新写法
需要依赖:
package.json
...
"@reduxjs/toolkit": "^2.8.2",
...
光这一个库,就包含了很多快捷写法:
- configureStore()
- createReducer()
- createAction()
- createSlice()
- combineSlices()
- createAsyncThunk
...
我这里只罗列了基本使用方法。从这个列表中的函数名就可以看出,@reduxjs/toolkit的模块化更清晰明确。
下面我们看看如何使用。
- 创建store
store.ts
import { configureStore } from "@reduxjs/toolkit";
import counter from "./modules/counter";
export default configureStore({
reducer: {
counter: counter,
},
});
- 创建一个reducer,就是上面的counter
counter.ts
import { createSlice } from "@reduxjs/toolkit";
const counterReducer = createSlice({
name: "Counter",
initialState: {
num: 0
},
reducers: {
add: (state, action) => {
state.num = state.num + 1;
},
minus: (state, action) => {
state.num = state.num - 1;
},
asyncAdd: (state, action) => {
setTimeout(() => {
state.num = state.num + 1;
}, 2000)
},
},
});
export const { add, minus, asyncAdd } = userReducer.actions;
export default counterReducer.reducer;
- 函数组件使用(不要再用component组件了)
index.tsx
import {
add,
} from "@/store/modules/counter";
...
const num = useSelector((state: any) => state.counter.num);
const dispatch = useDispatch();
const handleAddAction = () => dispatch(add())
...
到此结束。
通过上面的新老写法对比,新写法的简单几步就可以将以前复杂的action、state简化到一个文件中,并且功能清晰,我也相信你已经对@reduxjs/toolkit有了进一步了解,所以尽可能使用新的写法去简化我们的代码吧。
发布于2025-12-06 10:29:46
浏览量26·
暂无评论,快来发表第一条评论吧