如何使用 Redux 管理 React 应用中的状态。
在本教程中,你将使用 Redux 管理 React 应用的状态。Redux 可以帮助你在一个对象中跟踪和管理整个应用的状态,而无需将状态和逻辑放在顶层组件中。
你将使用 Redux 构建一个集中管理状态和逻辑的待办事项应用程序。
完成本教程后,您将了解:
-
Redux是什么,以及使用Redux进行状态管理的好处。
-
在待办事项应用中理解和使用 Redux 的概念,例如 store、reducer、actions 等。
本教程分为两部分。第一部分讲解关键概念、Redux架构以及Redux的基本用法。第二部分,我们将使用Redux构建一个待办事项应用,用于状态管理。
先决条件
为了更好地学习本教程,您应该熟悉以下内容:
-
JavaScript 中的函数
-
熟悉 React 术语:状态、JSX、组件、属性和 Hooks
-
构建一个基本的 React 应用
国家管理概论
React 使开发者能够轻松构建复杂的用户界面。为了给 UI 添加交互性,React 组件需要访问数据。这些数据可以是来自 API 端点的响应,也可以是应用内部定义的数据。当用户点击按钮或在输入框中输入内容时,这些数据会根据交互事件进行更新。
在 React 组件内部,数据存储在一个object名为 `data` 的变量中state。每当state数据发生变化时,组件都会重新渲染,React 会更新屏幕以在 UI 中显示新数据。
在 React 应用中,多个组件可能需要访问状态。因此,状态需要得到有效管理。有效的状态管理意味着能够在应用中存储和更新数据。
Redux是什么?
Redux 是一种用于管理和更新应用程序状态的模式和库,它使用称为“action”的事件。它充当一个集中式状态存储,用于存储需要在整个应用程序中使用的状态,并通过规则确保状态只能以可预测的方式更新。
使用 Redux,您可以拥有一个中央状态存储来维护、更新和监控应用程序的状态。这意味着,我们的组件可能不再需要自己的状态。状态将集中在一个位置,并且可以被应用程序中的多个组件访问。
Redux解决了什么问题?
一个基本的 React 应用可以分为以下几个部分:
-
状态:应用程序的当前状态
-
视图:应用程序的用户界面
-
操作:当应用程序中发生事件时更新状态的函数(通常称为事件处理程序)。
应用程序中的每个组件都可以拥有状态。然而,如果多个组件需要访问相同的数据,就会出现问题。为了解决这个问题,我们称之为“状态提升”。状态提升是指将状态从子组件移动到其父(顶层)组件的过程。通过这种方法,您可以轻松地在多个子组件之间共享状态。
然而,“提升国家地位”也有其弊端:
-
这样做会使你的代码变得复杂:将状态提升到父组件可能会在组件中添加大量样板代码。状态必须从父组件传递到子组件,这会导致代码冗余
prop-drilling。此外,状态也会在父组件中更新。 -
它会影响性能:当你将状态提升到组件层级时,状态改变时需要重新渲染的组件数量就会增加。这可能会影响性能,尤其是在移动设备上。
在大型单页应用程序中,我们的代码需要管理更多状态。这些状态可能包括服务器响应和缓存数据,以及尚未持久化到服务器的本地创建数据。最终,您将无法控制状态的更新时间、原因和方式,从而导致难以重现错误或添加新功能。
更好的方法是从父组件中提取共享状态,并将它们放在组件树之外的集中位置。
这种方法更好,因为:
-
它省去了螺旋桨钻孔。
-
无论组件位于何处,您都可以从父组件内的任何组件触发操作,并且可以修改其状态。
这就是 Redux 背后的理念。它帮助开发者管理全局状态(应用程序的许多部分都需要的状态),并使所有组件都能访问该状态,无论它们嵌套有多深。
Redux 的第一条规则是,应用程序中所有可以修改的内容都应该用一个名为 `Reux` state 或 `Reux.get`的单一对象来表示。 state tree.
使用 Redux 时需要了解一些关键术语。为了便于理解,我们首先会用一个类比来解释 Redux。之后,我们将在接下来的章节中对这些术语进行定义。
Redux 类比
想象一下,你是一家大型餐厅的管理合伙人。为了更好地管理餐厅,你决定密切关注餐厅的运营状况。
您可能需要追踪以下内容:
-
各种原料的库存情况
-
财务状况(每周收入和支出模式)
-
受雇厨师人数
-
雇佣的女服务员人数
-
每周客户等
把所有这些信息都记在脑子里会很麻烦。所以,你应该把它们保存在一个叫做“存储库”的中心位置(redux store)。
您雇佣了一名服务员(reducer),他是唯一可以更新商店信息的人。
有一些股东(components)依赖餐厅的状态(数据)来更新他们的投资组合(UI)。这些股东只能访问数据,而不能修改数据。
现在假设股东们聘请了一位新厨师,需要更新门店的数据。由于他们无法直接更新数据,股东可以dispatch向服务员发送一条包含新信息的便条。reducer服务员随后会将门店的旧数据更新为最新信息。
每当数据更新时,其他股东都会收到通知(subscribers),他们可以更新自己的投资组合(UI)。
了解 Redux 术语
以下是一些需要熟悉的新术语:
行动
Redux 的第二条规则是状态树 state 是只读的。你只能通过发送 `removeState` 来修改状态树 action。这确保了视图和网络回调都不会直接写入状态。相反,它们表达的是转换状态的意图。
换句话说,action这是更改应用程序的唯一推荐方法state。
操作描述了应用程序中发生的情况。它是一个 JavaScript 对象,作为参数传递给,并包含更新store所需的信息。storestate
在不同的应用程序中,所需参数action各不相同。例如,在计数器应用程序中,您只需要以下参数:actions:
-
数量增加
-
数量减少
在待办事项应用中,您可能会看到以下内容actions:
-
已添加待办事项
-
已删除待办事项
-
完成待办事项
-
筛选待办事项等。
使用 Redux,因为我们将状态state与组件分离,所以组件并不知道状态是如何变化的。它们只关心需要发送一个事件action。
该操作object有一个type属性,您可以在其中指定组件中发生的事件。这意味着每当发生事件时,事件处理函数都会分发一个action包含已发生事件信息的回调,以帮助更新statestore 中的数据。
它还action object具有一个payload属性。任何关于事件的新数据都将存储在该属性中payload。例如,当我分发“addedTodo”action事件时type,该属性payload可以包含新的待办事项及其 ID。
以下是一些action对象示例:
//action 1
const addTodoAction = {
type: 'todos/todoAdded', //what happened
payload: {todoID, newTodo} //data
}
//action 2
const getOrder = {
type: 'orders/getOrderStatus', //what happened
payload: {orderId, userID} //data
}
行动创造者
这些action creators函数会返回action对象。由于它们action creators包含可在应用程序多个实例中使用的逻辑,因此您可以向其传递一些parameters可在action对象中访问的参数。
以下是一些示例action creators:
//example 1
function addTodo(todo){
//return action object
return {
type: 'todos/addTodo',
payload: todo // what happened
}
}
//example 2
function getOrders(orderID, userID){
//return action object
return {
type: 'orders/getOrderStatus',
payload: {orderId, userID} //what happened
}
}
减速器
Areducer是一个纯函数,它接受当前状态state和一个新状态action作为参数arguments,并返回更新后的状态state。之所以称之为 reducer,是reducer因为与方法类似Array.reduce(),Redux reducer会将一系列操作随时间推移简化为一个单一状态。
reducer 应该是一个纯函数。纯函数是指对于相同的输入,它只会返回相同的输出。它不会改变或修改全局状态或任何其他函数的状态。
这意味着:
-
reducer 函数不允许修改当前值
state。相反,它们必须复制当前值state,然后更新复制的值。 -
reducer 函数不应该通过读取数据库来更新状态。
-
reducer 函数不应该调用任何第三方 API
以下是 reducer 函数的语法:
const myReducer = (state, action) => newState
reducer 函数内部的逻辑如下:
-
在函数体中,我们检查该
action.type属性。 -
如果
type操作与您定义的内容匹配,您将复制该操作state,并使用来自该操作的新值修改该状态。action.payload -
如果结果
action.type与您定义的任何内容都不匹配,则返回现有结果。state
以下是一个todoReducer函数示例:
const intialTodo = [{id:1, todo:""}]
const todoReducer = (state = initialTodo, action)=>{
if(action.type === "todos/AddedTodo"){
return [...state, todo: action.payload]
}else{
return state
}
}
以下是目前的情况:
-
在
if语句中验证是否action.type与右侧的表达式(action.type === "todos/AddedTodo")匹配。 -
如果确实如此,那么我们使用扩展运算符 (
...) 创建一个副本state,并使用从新待办事项数据中获取的数据更新该副本。action.payload -
否则,我们返回前一个值。
state
Redux 的第三个原则是,为了描述状态变化,你需要声明一个函数,该函数接受应用程序的先前状态、要分发的 action,并返回应用程序的下一个状态。
店铺
Astore是包含整个state应用程序的对象。它是数据的中心位置,也是数据更新的地方。
它store有三种主要方法:
-
getState()返回state应用程序的当前状态 -
dispatch(action)这是指示组件向 store 发送操作以更改state应用程序的方法。 -
subscribe(listener)该subscribe方法允许组件监听数据变化。它接受一个函数listener作为callback参数,该函数可以帮助您:- 更新用户界面以反映当前状态
- 当状态改变时,执行副作用或其他需要执行的任务。
下面是一个如何store在 Redux 中创建的示例。
//store.js
//import your root reducer
import rootReducer from "./rootReducer"
//import createStore from redux
import {createStore} from "redux"
//create the store
const store =createStore(rootReducer)
派遣
Dispatch 用于action向我们发送消息store。这是更改state我们应用程序的唯一方法。
要更新状态state,您需要调用该store.dispatch()方法。当dispatch()该方法被调用时,store 将执行 reducer(reducers 可以访问当前状态state和一个响应action作为输入,并执行一些逻辑)。然后,store 会使用 reducer 的输出更新其状态。
该store.dispatch()方法接受action对象作为参数。
store.dispatch({ type: 'todo/addedTodo' })
例如,在上面的代码片段中,每当用户输入一个新的待办事项时,你都会将操作分发给 `store` 。因为`store` 内部store有一个函数,它将使用分发的操作来确定新状态的逻辑。reduceraction.type
选择器
选择器是帮助你从中提取特定数据的函数state。它接受state一个参数,并返回要从中检索的数据state。
您将selector在组件中使用它来从状态中获取特定数据。
const selectLatestTodo = state => state.data //selector function
const currentValue = selectLastestTodo(store.getState())
console.log(currentValue)
// Buy milk
Redux架构示意图
在本节中,我们将使用所有学过的术语来解释我们的应用程序中的数据流,以及当状态改变时 UI 如何重新渲染。
我们来看看 Redux 的配置:
-
创建 Redux
store -
定义
reducer逻辑并将reducer函数传递给 store。该函数reducer接受 `stateand`action对象作为参数。 -
它将运行函数
store中的逻辑。reducer -
reducer 函数返回的值将成为应用程序的初始状态。
-
组件挂载时,会连接到 store,获取初始状态,并使用该状态显示 UI。由于组件已连接到 store,因此它可以访问任何状态更新。
正在更新状态:
-
应用中发生了一个事件。例如,添加了一个待办事项。
-
该组件将请求分发给
actionRedux。store -
它
store会重新运行该reducer函数。它可以访问之前的状态state(即action对象),并返回更新后的状态。 -
它会将状态变化
store通知所有连接的组件。 -
每个 UI 组件都会检查是否需要使用更新后的状态。
-
如果满足条件,它会使用新状态重新渲染用户界面,并更新屏幕上的内容。
创建store并subscribing调度actions
在本节中,我们将学习如何创建应用store以及dispatch对商店的操作。
Redux store 将我们应用程序的配置state、数据reducer和状态整合在一起action。它是应用程序状态的中心位置。
其功能store是:
-
保持应用程序的当前状态。
-
允许访问当前状态
-
允许更新状态
-
调度行动
-
订阅变更
创建商店
使用createStore()Redux 库中的方法来创建store。该方法接受一个reducer函数作为参数。
以下是创建商店的代码片段:
//store.js
import { createStore} from 'redux'
const store = createStore(rootReducer)
接下来,你需要将“根 reducer”函数传递给它createStore()。根 reducer 会将应用程序中的所有其他 reducer 合并在一起。
要创建根 reducer,你需要combineReducer()从 Redux 库导入相应的方法。该方法combineReducer可以帮助你组合所有不同的 reducer 函数。它接受一个objectreducer 函数对象作为参数。key该对象的键将成为根状态对象的键,而值则是相应的 reducer 函数。
以下是如何创建的示例rootReducer:
import { combineReducers } from 'redux';
const reducers = {
user: userReducer,
cart: cartReducer,
orders: ordersReducer,
};
const rootReducer = combineReducers(reducers);
现在,你已经学会了如何……
-
创建店铺
-
向 store 添加根 reducer
接下来,您将学习如何获取商店的初始状态并将操作分发到商店。
派往actionsstore
要更新state应用程序,组件需要分发操作。
以下是具体操作方法:
-
将其导入
store到您的应用程序中 -
调用这些
store.dispatch()方法并传递action对象。
//actions object
const addTodo = {
type: 'todos/todoAdded',
payload: "Buy milk"
});
const completeTodo = {
type: 'todos/todoRemoved',
payload: 2 // id of the todo to complete
}
//dispatch the action to update the state
store.dispatch(addTodo)
store.dispatch(completeTodo)
订阅商店
使用此subscribe()方法订阅应用商店。该subscribe()方法会监听state应用商店的更改。这将帮助您更新 UI 以反映当前商店state,执行副作用,或执行任何需要在商店state更改时完成的任务。
下面的代码片段演示了如何监听更新,并将最新状态记录到控制台:
const subscription = store.subscribe(() => {
// Do something when the state changes.
console.log('State after dispatch: ', store.getState())
});
将 Redux 添加到 React 应用中
在本节中,您将运用所学的概念,构建一个具有基本功能(添加、删除和完成待办事项)的待办事项应用程序,同时使用 redux 进行state管理。
由于我们之前已经介绍过相关概念,因此不会深入探讨每个具体实现方法。
以下是具体步骤:
-
设置您的 React 项目并安装所需的依赖项
-
为用户界面创建待办事项组件。
-
创建一个 Redux
store来跟踪和管理state你的应用程序 -
定义
reducer逻辑并连接到商店 -
调度
actions员更新state -
读取数据
store
项目代码仓库位于此处。它包含多个分支,分别对应我们将要实现的每个主要步骤。
让我们开始吧
步骤 1:设置您的项目
按照以下步骤在项目目录中创建一个 React 应用:
-
使用 Vite 从基本模板创建项目,在终端中运行以下命令:
npm create vite@latest my-react-app --template react // Replace "my-react-app" with the name of your project. -
在您的文件中安装
redux及其react-redux依赖项package.json。运行命令npm install redux react-redux --save这将安装核心 Redux 架构,并简化 React 应用与 Redux 的连接。
-
使用以下命令运行应用程序
npm run dev
步骤 2:创建待办事项组件
以下是我们应用程序的用户界面。
现在,让我们创建所需的组件。
-
在“src”目录中创建一个名为“components”的文件夹
-
创建应用程序用户界面所需的组件包括:
<TodoHeading/>包含标题文本<TodoInput/>输入待办事项的输入框<TodoItem/>显示单个待办事项,带有删除和完成按钮<TodoList/>显示待办事项列表。
步骤 3:创建store
接下来,我们需要创建一个控制器store来跟踪和管理整个state应用程序。我们使用createStore()Redux 中的方法来实现这一点。
请按照以下步骤操作:
-
在应用的根目录下创建一个名为“store”的文件夹。
-
store.js在“store”文件夹中创建一个文件 -
createStore从 Redux导入该方法 -
调用该
createStore()方法,并将作为参数传递todoReducer(我们将在下一步中定义它)。 -
导出
store以便在 React 应用中使用
//store/store.js
import { createStore } from "redux";
import todoReducer from "../reducer/todoReducer";
const store = createStore(todoReducer);
export default store;
步骤 4:定义reducer函数
我们将在一个文件中定义 reducer。ReducertodoReducer.js是包含更新状态所需逻辑并返回新状态的函数。它todoReducer.js还将包含应用程序的初始状态。
按照以下步骤定义reducer函数:
- 创建一个
todoReducer.js内部“reducer”文件夹
将以下代码片段添加到文件中
//state object
const initialState = {
todos: [
{
id: 1,
item: "Learn redux fundamentals",
completed: false,
},
{
id: 2,
item: "Build a todo-app",
completed: false,
},
],
};
//define the reducer logic
const todoReducer = (state = initialState, action) => {
switch (action.type) {
//logic to add a new todo
case "todos/addedTodo":
return {
...state,
todos: [...state.todos, action.payload],
};
//logic to delete a todo
case "todos/deleteTodo":
return {
...state,
todos: state.todos.filter((todo) => todo.id !== action.payload),
};
// logic to complete a todo
case "todos/completeTodo":
return {
...state,
todos: state.todos.map((todo) => {
if (todo.id === action.payload) {
return {
...todo,
completed: !todo.completed,
};
} else {
return todo;
}
}),
};
default:
return state;
}
};
export default todoReducer;
在上面的代码中:
-
我们添加了应用程序的首字母
state。它预先填充了一些array待办事项,以便在应用程序渲染时显示一些虚拟数据。 -
我们定义该
todoReducer函数。该函数接受 `stateand`action对象作为参数。 -
在函数体中,我们实现了一个
switch语句。根据表达式(action.type),每个语句都包含一个逻辑,case用于决定如何state更新和返回值。 -
最后,我们
export将todoReducer其作为参数传递给该createStore()方法(如前所述)。
步骤 5:将Provider组件包裹在你的应用周围
该Provider组件使 Reduxstore可供任何需要访问它的嵌套组件使用store。
由于 React Redux 应用中的任何 React 组件都可以连接到 store,因此大多数应用都会Provider在顶层渲染一个组件,并将整个应用的组件树包含在其中。
以下是如何将根组件包裹在……之中Provider
-
导入
storemain.jsx -
Provider从“react-redux”导入组件 -
将根组件包裹
<App/>在Provider -
它
Provider接受一个props,其值为store导入的内容。store
//main,jsx
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App.jsx";
import "./index.css";
import { Provider } from "react-redux"; //Provider
import store from "./store/store.js"; //store
ReactDOM.createRoot(document.getElementById("root")).render(
<React.StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>
);
在上面的代码中,我们<Provider/>对<App/>组件进行了包装,以使所有嵌套组件都能访问该组件。store
useSelector接下来,我们将使用钩子从商店读取并显示数据。
useSelector步骤 6:使用钩子读取和显示待办事项
React-Redux 拥有自定义的 Hook,你可以在组件中使用这些 Hook。该useSelectorHook允许 React 组件从 Redux store 中读取数据。它接受一个选择器函数,该函数以整个 Redux store 状态作为参数,从状态中读取某个值,并返回该结果。
请按照以下步骤读取和显示数据:
-
useSelector从“react-redux”导入 -
调用该
useSelector()方法。它接受一个选择器函数作为回调函数。 -
todos从……返回state
以下代码演示了如何todos从我们的商店读取数据。
//components/TodoList.jsx
import React from "react";
import { useSelector } from "react-redux";
import TodoItem from "./TodoItem";
const TodoList = () => {
//callback function
const selectTodos = (state) => state.todos;
//extract the todos
const returnedTodos = useSelector(selectTodos);
const displayTodos = returnedTodos.map((todo) => (
<TodoItem key={todo.id} todo={todo} />
));
return <div>{displayTodos}</div>;
};
export default TodoList;
让我们来理解上面的代码:
-
组件首次
<TodoList/>渲染时,该useSelector钩子函数将执行selectTodos回调函数。 -
返回的值
selectTodos将由钩子返回,useSelector供我们的组件使用。 -
它将保存与Redux store 状态内部
const returnedTodos相同的数据。state.todos -
我们使用 JavaScript
map()方法遍历每个待办事项,并显示单个待办事项。 -
它
useSelector会自动订阅Redux store。因此,每当actiondispatch 一个事件时,它都会调用该selectTodos函数。如果该函数返回的值selectTodos已更新,useSelector则会强制TodoList组件使用新数据重新渲染。
我们知道如何从数据存储中读取和显示数据store。接下来,我们将学习如何从组件分发操作来更新数据存储。
useDispatch步骤 5:使用钩子分发操作
该钩子提供了对分发更新所需的方法useDispatch的访问。dispatchactionsstate
我们可以调用const dispatch = useDispatch()任何需要分发操作的组件,然后dispatch(someAction)根据需要进行调用。
在TodoInput组件中,我们来发送一个 action 来添加一个新的待办事项:
-
useDispatch从“react-redux”导入 -
调用该
useDispatch()方法。它返回dispatch函数。 -
输入并提交新的待办事项
-
调用该
dipatch()方法addTodo并传递action对象//components/TodoInput.jsx import React, { useState } from "react"; import { useDispatch } from "react-redux"; const TodoInput = () => { const [todo, setTodo] = useState(""); const dispatch = useDispatch(); const onInputTodo = (e) => { setTodo(e.target.value); }; //handle submission of todo const handleTodoSubmit = (e) => { e.preventDefault(); addTodo(); // addTodo setTodo(""); }; //action creators const addTodo = () => { //dispatch action to add a todo return dispatch({ type: "todos/addedTodo", payload: { id: Math.floor(Math.random() * 20) + 1.1, item: todo }, }); }; return ( <div> <form className="todo_form_container" onSubmit={handleTodoSubmit}> <input className="todo_input" type="text" placeholder="Enter your todo" value={todo} onChange={onInputTodo} /> <button className="todo_btn">Add Todo</button> </form> </div> ); }; export default TodoInput;
在上面的代码中,提交新的待办事项时:
-
该
handleTodoSubmit函数执行该addTodo()函数 -
它将对象分
addTodo()发给函数以进行更新。actiontodoReducerstate
因为我们已经导入了useSelector钩子,所以我们可以轻松地向商店状态添加新的待办事项,并且它会反映在用户界面中。
以下是我们目前为止所完成的工作。
-
创建
store -
将 `<store>` 标签包裹
<Provider store={store}>在顶级<App>组件周围,以使所有其他组件都能访问和更新存储。 -
调用
useSelector钩子函数以在 React 组件中读取数据 -
调用
useDispatchhook 来分发 React 组件中的 action
点击“删除”和“完成”按钮后执行相应操作
在TodoItem组件中,我们现在可以点击“删除”和“完成”按钮。点击这些按钮后,我们会分发删除和完成待办事项的操作。这些操作在 ` onDeleteand`onComplete操作创建器中处理。
代码片段如下:
//components/TodoItem.jsx
import { useDispatch } from "react-redux";
const TodoItem = ({ todo }) => {
const dispatch = useDispatch();
//delete a todo
const onDelete = (id) => {
return dispatch({
type: "todos/deleteTodo",
payload: id,
});
};
//complete Todo
const onComplete = (id) => {
return dispatch({
type: "todos/completeTodo",
payload: id,
});
};
return (
<div>
<h3 className={`todo${todo.completed ? "Completed" : ""}`}>
{todo.item}
</h3>
<div>
<button onClick={() => onComplete(todo.id)}>Complete</button>
<button onClick={() => onDelete(todo.id)}>Delete</button>
</div>
</div>
);
};
export default TodoItem;
- 点击“删除”和“完成”按钮分别调用 `delete` 和 `complete` 函数。`delete`函数会向 `
onDelete()create`对象发送删除指定项的操作,而 `complete` 函数会向 `create` 对象发送完成所选项的操作。onCompleteonDeletetodoReduceronCompletetodoReducer
Redux 与 Context API 的比较
Redux 和 Context API 的区别在于它们管理状态的方式。Redux 将状态集中存储在一个中央 store 中。而 Context API 则在组件级别处理状态更新,因为状态更新发生在每个组件内部。
你可能会问,既然这样可以避免使用问号,为什么不使用useContextContext API 中的 hook 来将状态传递给多个组件呢prop drilling?
如果某个状态会影响多个组件,或者应用中的所有组件都需要它,你可以使用useContext钩子来管理它state。这样可以避免 props 层层传递,并使所有组件都能轻松访问数据。
然而,使用以下方法也存在一些缺点useContext:
-
该
useContext钩子设置较为复杂:在构建企业级应用时,多个组件可能需要访问state该钩子,因此您可能需要使用contextAPI 创建多个上下文,并为每个上下文提供应用不同方面所需的数据。例如,您将创建- 身份验证上下文:方便用户进行身份验证
- 主题上下文:用于更改主题。例如,启用深色模式。
- 表单上下文:用于将表单数据传递给表单组件等。
这种现象可能导致需要创建多个上下文来满足特定需求,从而导致应用程序中出现深度嵌套的上下文提供程序组件。
-
其次,
useContext它并未针对状态频繁变化的企业级应用进行优化。这将降低应用的性能。 -
最后,在使用时
useContext,UI 逻辑和状态管理将位于同一个组件中。
以下是一些你可能使用 Redux 的场景useContext:
-
您的应用程序中有很多状态,而且这些状态在应用程序的很多地方都是必需的。
-
应用程序状态会随时间频繁更新
-
更新该状态的逻辑可能很复杂。
-
该应用的代码库规模中等或较大,可能由多个开发人员共同开发。
结论
在本教程中,您使用 Redux 管理了 React Todo 应用的状态。接下来,我们将学习如何使用Redux Toolkit管理状态。Redux Toolkit 可以简化编写优秀 Redux 应用的过程,并加快开发速度。此外,您还将学习 Redux DevTools,它可以帮助您追踪应用状态何时、何地、为何以及如何发生变化。
文章来源:https://dev.to/efkumah/how-to-manage-state-in-a-react-app-using-redux-5pc





