共计 4469 个字符,预计需要花费 12 分钟才能阅读完成。
理解 Redux Toolkit,这是用于高效 Redux 开发的通过验证的工具集。在本文中,你将看到为什么 Redux Toolkit 值得 React 社区更多的关注。
React 和 Redux 被认为是大规模 React 利用中治理状态的最佳组合。然而,随着工夫的推移,Redux 的受欢迎水平降落,起因是:
- 配置 Redux Store 并不简略。
- 咱们须要几个软件包来使 Redux 与 React 一起工作。
- Redux 须要太多样板代码。
带着这些问题,Redux 的创建者 Dan Abramov 发表了名为《你可能不须要 Redux》的文章,倡议人们只在须要的时候应用 Redux,而在开发不那么简单的利用时,要遵循其余办法。
Redux Toolkit 解决的问题
Redux Toolkit(之前称为 Redux Starter Kit)提供了一些选项来配置全局 store,并通过尽可能地形象 Redux API 来更精简地创立动作和 reducers。
它包含什么?
Redux Toolkit 附带了一些有用的软件包,例如 Immer,Redux-Thunk 和 Reselect。它使 React 开发人员的工作变得更加轻松,容许他们间接更改状态(不解决不可变性),并利用 Thunk 之类的中间件(解决异步操作)。它还应用了 Redux 的一个简略的“选择器”库 Reselect 来简化 reducer 函数。
Redux Toolkit API 的次要性能?
以下是 Redux Took Kit 应用的 API 函数,它是现有 Redux API 函数的形象。这些函数并没有扭转 Redux 的流程,只是以更易读和治理的形式简化了它们。
- configureStore:像从 Redux 中创立原始的 createStore 一样创立一个 Redux store 实例,但承受一个命名的选项对象并主动设置 Redux DevTools 扩大。
- createAction:承受一个 Action 类型字符串,并返回一个应用该类型的 Action 创立函数。
- createReducer:承受初始状态值和 Action 类型的查找表到 reducer 函数,并创立一个解决所有 Action 类型的 reducer。
- createSlice:承受一个初始状态和一个带有 reducer 名称和函数的查找表,并主动生成 action creator 函数、action 类型字符串和一个 reducer 函数。
您能够应用上述 API 简化 Redux 中的样板代码,尤其是应用 createAction 和createReducer办法。然而,这能够应用 createSlice 进一步简化,它能够主动生成 action creator 和 reducer 函数。
createSlice 有什么特别之处?
它是一个生成存储片的助手函数。它承受片的名称、初始状态和 reducer 函数来返回 reducer、action 类型和 action creators。
首先,让咱们看看在传统的 React-Redux 应用程序中 reducers 和 actions 的样子。
Actions
import {GET_USERS,CREATE_USER,DELETE_USER} from "../constant/constants";
export const GetUsers = (data) => (dispatch) => {
dispatch({
type: GET_USERS,
payload: data,
});
};
export const CreateUser = (data) => (dispatch) => {
dispatch({
type: CREATE_USER,
payload: data,
});
};
export const DeleteUser = (data) => (dispatch) => {
dispatch({
type: DELETE_USER,
payload: data,
});
};
Reducers
import {GET_USERS,CREATE_USER,DELETE_USER} from "../constant/constants";
const initialState = {
errorMessage: "",
loading: false,
users:[]};
const UserReducer = (state = initialState, { payload}) => {switch (type) {
case GET_USERS:
return {...state, users: payload, loading: false};
case CREATE_USER:
return {...state, users: [payload,...state.users],
loading: false };
case DELETE_USER:
return { ...state,
users: state.users.filter((user) => user.id !== payload.id),
, loading: false };
default:
return state;
}
};
export default UserReducer;
当初,让咱们看看如何应用 createSlice 简化并实现雷同的性能。
import {createSlice} from '@reduxjs/toolkit';
export const initialState = {users: [],
loading: false,
error: false,
};
const userSlice = createSlice({
name: 'user',
initialState,
reducers: {getUser: (state, action) => {
state.users = action.payload;
state.loading = true;
state.error = false;
},
createUser: (state, action) => {state.users.unshift(action.payload);
state.loading = false;
},
deleteUser: (state, action) => {state.users.filter((user) => user.id !== action.payload.id);
state.loading = false;
},
},
});
export const {createUser, deleteUser, getUser} = userSlice.actions;
export default userSlice.reducer;
正如你所看到的,当初所有的动作和 reducer 都在一个简略的中央,而在传统的 redux 利用中,你须要在 reducer 中治理每一个 action 和它对应的 action,当应用 createSlice 时,你不须要应用开关来辨认 action。
当波及到渐变状态时,一个典型的 Redux 流程会抛出谬误,你将须要非凡的 JavaScript 策略,如 spread operator 和 Object assign 来克服它们。因为 Redux Toolkit 应用 Immer,因而您不用放心会扭转状态。因为 slice 创立了 actions 和reducers,你能够导出它们,并在你的组件和 Store 中应用它们来配置 Redux,而无需为 actions 和reducers建设独自的文件和目录,如下所示。
import {configureStore} from "@reduxjs/toolkit";
import userSlice from "./features/user/userSlice";
export default configureStore({
reducer: {user: userSlice,},
});
这个存储能够通过应用 useSelector 和useDispatch的 redux api 间接从组件中应用。请留神,您不用应用任何常量来标识操作或应用任何类型。
解决异步 Redux 流
为了解决异步动作,Redux Toolkit 提供了一个非凡的 API 办法,称为createAsyncThunk,它承受一个字符串标识符和一个 payload 创建者回调,执行理论的异步逻辑,并返回一个 Promise,该 Promise 将依据你返回的 Promise 解决相干动作的调度,以及你的 reducers 中能够解决的 action 类型。
import axios from "axios";
import {createAsyncThunk} from "@reduxjs/toolkit";
export const GetPosts = createAsyncThunk("post/getPosts", async () => await axios.get(`${BASE_URL}/posts`)
);
export const CreatePost = createAsyncThunk("post/createPost",async (post) => await axios.post(`${BASE_URL}/post`, post)
);
与传统的数据流不同,由 createAsyncThunk 解决的 action 将由分片内的 extraReducers 局部解决。
import {createSlice} from "@reduxjs/toolkit";
import {GetPosts, CreatePost} from "../../services";
export const initialState = {posts: [],
loading: false,
error: null,
};
export const postSlice = createSlice({
name: "post",
initialState: initialState,
extraReducers: {[GetPosts.fulfilled]: (state, action) => {state.posts = action.payload.data;},
[GetPosts.rejected]: (state, action) => {state.posts = [];
},
[CreatePost.fulfilled]: (state, action) => {state.posts.unshift(action.payload.data);
},
},
});
export default postSlice.reducer;
请留神,在 extraReducers 外部,您能够解决已解决(fulfilled)和已回绝(rejected)状态。
通过这些代码片段,您能够看到此工具包在 Redux 中简化代码的成果如何。我创立了一个利用 Redux Toolkit 的 REST 示例供您参考。
最初的想法
依据我的教训,当开始应用 Redux 时,Redux Toolkit 是一个很好的抉择。它简化了代码,并通过缩小模板代码来帮忙治理 Redux 状态。
最初,就像 Redux 一样,Redux Toolkit 并非仅为 React 构建。咱们能够将其与其余任何框架(例如 Angular)一起应用。
您能够通过参考 Redux Toolkit 的文档找到更多信息。
谢谢您的浏览!