简介
Redux Toolkit包旨在成为编写Redux逻辑的标准方式。它最初的创建是为了帮助解决关于 Redux 的三个常见问题:
“配置 Redux 存储太复杂了”
“我必须添加很多包才能让 Redux 做任何有用的事情”
“Redux 需要太多样板代码”
我们无法解决所有用例,但本着create-react-appand的精神apollo-boost,我们可以尝试提供一些工具来抽象设置过程并处理最常见的用例,并包含一些有用的实用程序,让用户简化他们的应用程序代码。
Redux Toolkit 还包括一个强大的数据获取和缓存功能,我们称之为“RTK Query”。它作为一组单独的入口点包含在包中。它是可选的,但可以消除您自己手写数据获取逻辑的需要。
这些工具应该对所有 Redux 用户都有益。无论您是设置第一个项目的全新 Redux 用户,还是想要简化现有应用程序的经验丰富的用户,Redux Toolkit都可以帮助您改进您的 Redux 代码。
安装
使用 React 和 Redux 启动新应用程序的推荐方法是使用官方 Redux+JS 模板或Redux+TS 模板来创建 React App,它利用了Redux Toolkit和 React Redux 与 React 组件的集成。
- 快速创建项目 (jsx类型)
npx create-react-app my-app --template redux
- 快速创建项目 (tsx类型)
npx create-react-app my-app --template redux-typescript
- 如果已有项目
npm install @reduxjs/toolkit or yarn add @reduxjs/toolkit
api
Redux Toolkit 包括以下 API:
- configureStore(): 包装createStore以提供简化的配置选项和良好的默认值。它可以自动组合你的 slice reducer,添加你提供的任何 Redux 中间件,redux-thunk默认包含,并启用 Redux DevTools Extension。
import { configureStore } from '@reduxjs/toolkit'; import counterReducer from '../features/counter/counterSlice'; // configureStore创建了一个redux数据 export const store = configureStore({ reducer: { counter: counterReducer, }, });
- createReducer():这使您可以为 case reducer 函数提供操作类型的查找表,而不是编写 switch 语句。此外,它自动使用该immer库让您使用普通的可变代码编写更简单的不可变更新,例如state.todos[3].completed = true.
- createAction():为给定的动作类型字符串生成动作创建函数。该函数本身已toString()定义,因此可以使用它来代替类型常量。
import { createAction, createReducer } from '@reduxjs/toolkit' const increment = createAction('counter/increment') const decrement = createAction('counter/decrement') const incrementByAmount = createAction('counter/incrementByAmount') const initialState = { value: 0 } const counterReducer = createReducer(initialState, (builder) => { builder .addCase(increment, (state, action) => { state.value++ }) .addCase(decrement, (state, action) => { state.value-- }) .addCase(incrementByAmount, (state, action) => { state.value += action.payload }) })
- createSlice():接受reducer函数的对象、切片名称和初始状态值,并自动生成切片reducer,并带有相应的动作创建者和动作类型。
- createAsyncThunk: 接受一个动作类型字符串和一个返回承诺的函数,并生成一个pending/fulfilled/rejected基于该承诺分派动作类型的 thunk
import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'; import { fetchCount } from './counterAPI'; const initialState = { value: 0, status: 'idle', }; export const incrementAsync = createAsyncThunk( 'counter/fetchCount', async (amount) => { const response = await fetchCount(amount); return response.data; } ); export const counterSlice = createSlice({ name: 'counter', initialState, reducers: { increment: (state) => { state.value += 1; //内置了immutable }, decrement: (state) => { state.value -= 1; }, incrementByAmount: (state, action) => { state.value += action.payload; }, }, extraReducers: (builder) => { builder .addCase(incrementAsync.pending, (state) => { state.status = 'loading'; }) .addCase(incrementAsync.fulfilled, (state, action) => { state.status = 'idle'; state.value += action.payload; }); }, }); export const { increment, decrement, incrementByAmount } = counterSlice.actions; export const selectCount = (state) => state.counter.value; export const incrementIfOdd = (amount) => (dispatch, getState) => { const currentValue = selectCount(getState()); if (currentValue % 2 === 1) { dispatch(incrementByAmount(amount)); } }; export default counterSlice.reducer;//默认导出
- createEntityAdapter: 生成一组可重用的 reducer 和 selector 来管理 store 中的规范化数据
- 重新选择库中的createSelector实用程序,重新导出以方便使用。