React Redux | 通过项目轻松学习 Redux
💥💥 React Redux 示例 💥💥
💥💥 行动 💥💥:
💥💥 减量器 💥💥 :
💥💥 店铺 💥💥 :
mapStateToProps() 🤑🤑:
mapDispatchToProps() 😁😁:
全部完成🙌🎉🎉
💥💥 React Redux 示例 💥💥
这是一个用于理解 React 中 Redux 概念的待办项目,本项目引用了此GitHub 项目。
Redux是什么?
Redux 用于应用程序的状态管理。它的主要优势在于解决了组件间“props 传递不畅”的问题。
例如,假设我们有 4 个组件,分别名为 A、B、C、D,它们的表示形式如下:
A(父组件)
|
B
|
C
|
D(叶组件)
我们有一个名为itemCode 的属性,它在组件A中生成,并且仅在组件D中使用。Traditional Way原本是要将该 itemCode 作为属性传递给B,然后传递给C,最后传递给D。
😎😎 How Redux Solves它为应用程序创建了一个存储库,将应用程序的所有状态集中保存在一个地方。因此,当组件A生成 itemCode 时,组件A不会将其作为 props 一直传递到组件D,而是将该 itemCode 存储在存储库中,然后组件D从存储库中获取 itemCode 值。
注意, props到底有什么问题呢🙄🙄?
这个待办事项应用规模很小,在大型项目中,props的数量可能高达10个、20个、甚至100个,所以到处使用props会让应用变得非常非常复杂🤯🤯🤯
让我们深入了解 Redux 的工作原理。
首先,我们来搭建基本项目。
- 创建一个新的 React 项目
npx create-react-app todo_redux - 安装 Redux 依赖项
npm install react-redux redux - 创建一个名为action和reducer 的文件夹
/src - 在action文件夹内,创建 2 个文件
/action-types.js,/todo.js - 在reducer文件夹中,创建名为
/todo.js - 在/src文件夹中,创建一个名为“
store.js
但这些 Action、Reducer 和 Store 分别是什么呢?
💥💥 行动 💥💥:
它包含的逻辑会告诉Reducer what should be done何时调用开发者创建的特定命令。例如,在我们的例子中,创建了两个 action:
- 添加待办事项
- 移除待办事项
所以,Action 会告诉 Reducer,好的,组件调用了 Add Todo,所以,嘿 Reducer,我们现在需要添加一个包含这些详细信息的 todo。
操作语法:
import { ADD_TODO } from "./action-types";
export const addTodo = (todo) => ({
type: ADD_TODO,
payload: todo,
});
addTodo是一个包的名称,它返回一个包含必填字段“type”和可选字段“payload”的对象。
- 类型:用于验证 reducer 端的操作,确认是否接收到类型为 blah blah 😜 的操作,以及是否需要执行与此类型相关的逻辑 🙈
- 有效载荷:有时在 reducer 端,会发送一些数据,用于更新 store 中的状态。
💥💥 减量器 💥💥 :
到目前为止,我们已经有了how to do ?定义在 reducer 文件中的 action,它指示要执行的操作。在我们的例子中,当收到 addTodo action 时,应该如何处理 state/store?我们需要将从 action 包中接收到的 todo 及其详细信息添加到 store 中,store 中已经包含一些之前的 todo,并返回 store 中 todo 的更新状态。
Reducer 的语法
import { ADD_TODO } from "../action/action-types";
const initialState = [];
export const todos = (state = initialState, action) => {
switch (action.type) {
case ADD_TODO:
return [...state, action.payload];
default:
return state;
}
};
这里可以看到操作的类型字段发挥作用了,它用于验证调用特定类型的操作时要执行的逻辑。以及用于更新状态/存储的有效负载数据。
可以有多个文件,每个文件包含多个 reducer,但最终我们会将所有文件中的 reducer 合并成一个根 reducer,因为 store 只需要一个 reducer。(本文稍后会介绍具体方法)
💥💥 店铺 💥💥 :
Store 用于保存应用程序的所有状态。Store是只读的,更新状态只能通过 reducer 来实现。
此外,整个应用程序只会有一个 Store。
商店的语法
import { createStore, combineReducers } from "redux";
import { todos } from "./reducer/todo";
const rootReducer = combineReducers(
todos
});
const store = createStore(rootReducer);
export default store;
在这里,我们导入所有 reducer 文件,并借助combineReducers它们将它们合并成 1 个 reducer,然后为createStore应用程序创建一个 store。
到目前为止,我们已经创建了一个Store包含根 reducers 的组件,它整合了所有 reducers,Action分别负责定义做什么和Reducer如何做。现在的问题是如何从组件访问 store?🤷♀️🤷♀️🤷♀️
首先,我们需要将主父组件包裹在 App.js 中。<Provider store={store}> all the components comes here </Provider >
Provider是react-redux一个神奇的东西,它处理所有工作,并将它传递给store ,而 store 是从store 文件导入的。
现在正在将组件连接到商店✌✌:
我们需要使用两个函数,它们将通过 action 和 reducer 获取数据并将其发送到存储中,完成整个流程。
隆重推出:
mapStateToProps() 🤑🤑:
此函数用于从 store 中获取数据并将其作为 prop 传递给组件,之后在组件中,它像使用 props 中的值一样以传统方式使用。
mapStateToProps() 的语法
const mapStateToProps = (state) => ({
todos: state.todos,
});
在组件中,它将作为 props 访问。
const TodoForm = ({ todos }) => {};
mapDispatchToProps() 😁😁:
此函数用于准备 action 包,该 action 包随后会传递给 reducer 以更新应用程序的状态。例如,在我们的示例中,我们需要添加一个包含待办事项详情的待办事项,因此我们需要准备一个类型为 addtodo 的 action。
mapDispatchToProps() 的语法
const mapDispatchToProps = (dispatch) => ({
addTodo: (todo) => {
dispatch(addTodo(todo));
},
});
在组件中,它将作为 props 访问。
const TodoForm = ({ addTodo }) => {};
