简介
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
oryarn 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实用程序,重新导出以方便使用。