React library快速入门——Redux Toolkit

2,248 阅读3分钟

这是我参与11月更文挑战的第20天,活动详情查看:2021最后一次更文挑战

介绍

Redux Toolkit是Redux官方的一个工具包。根据它官网的介绍:

The official, opinionated, batteries-included toolset for efficient Redux development

理解一个lib,首先要理解它的官方介绍。这句话的里包含了几个关键的信息

  • opinionated: 字面意思是武断、固执己见的。在这里表示这个库有自己的设计理念和实践原则,如果加上official,可以一定程度上认为这个库代表着redux的最佳实践(个人认为的确也是最佳实践)
  • batteries-included: 字面意思是内置了电池。比如买了一个玩具,不用担心它需要配几号电池,打开后简单组装就能用。在编程中,它的引申义不是开箱即用,但可以理解为功能完备。
  • toolset: 工具集,这意味着这个库可能是将几个工具组合起来,以及我们可能需要理解有哪些工具,以及Redux Toolkit是如何组装它的(这些工具不一定是它自带的)。

Redux的痛点

用过Redux的人一定对下面这些痛点有深刻的感受。

  • 模板太多,多个目录和文件切换太痛苦
  • 类型定义很困难
  • 需要配合多种工具使用,比如下面这段代码

image.png

使用

Redux Toolkit能很好地解决上面这些问题。

创建store:

import {configureStore} from '@reduxjs/toolkit';
import logger from 'redux-logger';

import demoReducer, {initDemoState} from './demoReducer';
import commonReducer, {initCommonState} from './commonReducer';

export type StateType = {demo: typeof initDemoState; common: typeof initCommonState};

export const initState: StateType = {
	demo: initDemoState,
	common: initCommonState
};
// toolkit将大大简化创建store的操作,默认集成了thunk,immutable
const store = configureStore({
	reducer: {
		demo: demoReducer,
		common: commonReducer
	},
	middleware: getDefaultMiddleware => getDefaultMiddleware().concat(logger),
	preloadedState: initState,
	devTools: true
});
export default store;

Redux Toolkit集成了thunk,immutable,不需要再引入和配置。配置logger和devTool也很简单。

编写reducer

//toolkit将大大简化redux开发,并解决类型问题
import {createSlice, PayloadAction} from '@reduxjs/toolkit';
import {demoApi} from '@/api/DemoApi';
export const initDemoState: {text: string} = {
	text: ''
};
export const demoSlice = createSlice({
	name: 'demo',
	initialState: initDemoState,
	reducers: {
		// 使用toolkit,不需要返回一个新的state
		setText: (state, action: PayloadAction<string>) => {
			const {payload} = action;
			state.text = payload;
		}
	}
});

// 使用toolkit,不需要创建action文件
export const {setText} = demoSlice.actions;

export const fetchText = () => async dispatch => {
	return demoApi.fetchText().then(data => {
		dispatch(setText(data.text));
		return data;
	});
};

export default demoSlice.reducer;

以前可能需要分三个文件:

image.png

而现在只需要一个文件。

另外,以前对state的合并操作非常痛苦,尤其是对数组操作的时候,但是用了Redux Toolkit后可以放心地操作state:

image.png

引入状态和派发action:

import React, {useEffect, useState} from 'react';
import {useDispatch, useSelector} from 'react-redux';
import {fetchText} from '@/store/demoReducer';
import store, {StateType} from '@/store';
export default function HomePage() {
    const dispatch = useDispatch<typeof store.dispatch>();
	const content = useSelector((state: StateType) => ({
		text: state.demo.text
	}));
	const getText = () => {
		return dispatch(fetchText()).then(res => {
			console.log(res);
		});
	};
	useEffect(() => {
		getText();
	}, []);
        ...
}

如果前面定义的类型都是能让ts进行推导的话,那么编程的时候就会有便捷的类型提示:

image.png

总结

个人觉得按照这个lib进行代码组织,不需要进行复杂的配置,没有各种模板目录和代码,每个模块的state分别作为一个slice,项目结构干净,类型定义简单,真的可以说是Redux的最佳实践了。如果项目中选择Redux作为状态管理库的话,强烈推荐这个工具。