Redux 要点,第 1 部分:Redux 概述和概念
Redux 是什么以及你可能想要使用它的原因
¥What Redux is and why you might want to use it
Redux 的关键术语和概念
¥Key Redux terms and concepts
数据如何流经 Redux 应用
¥How data flows through a Redux app
介绍
¥Introduction
欢迎来到 Redux Essentials 教程!本教程将向你介绍 Redux,并教你如何使用我们最新推荐的工具和最佳实践来正确使用它。完成后,你应该能够开始使用在这里学到的工具和模式构建自己的 Redux 应用。
¥Welcome to the Redux Essentials tutorial! This tutorial will introduce you to Redux and teach you how to use it the right way, using our latest recommended tools and best practices. By the time you finish, you should be able to start building your own Redux applications using the tools and patterns you've learned here.
在本教程的第 1 部分中,我们将介绍使用 Redux 时需要了解的关键概念和术语,在 第 2 部分:Redux 应用结构 中,我们将研究一个基本的 React + Redux 应用,以了解各个部分如何组合在一起。
¥In Part 1 of this tutorial, we'll cover the key concepts and terms you need to know to use Redux, and in Part 2: Redux App Structure we'll examine a basic React + Redux app to see how the pieces fit together.
从 第 3 部分:基本 Redux 数据流 开始,我们将利用这些知识构建一个具有一些现实世界功能的小型社交媒体源应用,了解这些部分在实践中如何实际工作,并讨论使用 Redux 的一些重要模式和指南。
¥Starting in Part 3: Basic Redux Data Flow, we'll use that knowledge to build a small social media feed app with some real-world features, see how those pieces actually work in practice, and talk about some important patterns and guidelines for using Redux.
如何阅读本教程
¥How to Read This Tutorial
本页面将重点向你展示如何正确使用 Redux,并解释足够的概念,以便你能够理解如何正确构建 Redux 应用。
¥This page will focus on showing you how to use Redux the right way, and explain just enough of the concepts so that you can understand how to build Redux apps correctly.
我们试图让这些解释对初学者友好,但我们确实需要对你已经知道的内容做出一些假设:
¥We've tried to keep these explanations beginner-friendly, but we do need to make some assumptions about what you know already:
熟悉 HTML 和 CSS。
¥Familiarity with HTML & CSS.
熟悉 ES2015 语法和特性
¥Familiarity with ES2015 syntax and features
React 术语知识:JSX、状态、函数组件、属性 和 钩子
¥Knowledge of React terminology: JSX, State, Function Components, Props, and Hooks
异步 JavaScript 和 发出 AJAX 请求 的知识
¥Knowledge of asynchronous JavaScript and making AJAX requests
如果你还不熟悉这些主题,我们鼓励你先花一些时间熟悉它们,然后再回来了解 Redux。当你准备好时,我们会在这里!
¥If you're not already comfortable with those topics, we encourage you to take some time to become comfortable with them first, and then come back to learn about Redux. We'll be here when you're ready!
你应该确保你的浏览器中安装了 React 和 Redux DevTools 扩展:
¥You should make sure that you have the React and Redux DevTools extensions installed in your browser:
React 开发工具扩展:
¥React DevTools Extension:
Redux DevTools 扩展:
¥Redux DevTools Extension:
什么是 Redux?
¥What is Redux?
它有助于首先理解 "Redux" 的东西是什么。它有什么作用?它能帮我解决什么问题?我为什么要使用它?
¥It helps to understand what this "Redux" thing is in the first place. What does it do? What problems does it help me solve? Why would I want to use it?
Redux 是一种模式和库,用于使用名为 "actions" 的事件来管理和更新应用状态。它充当需要在整个应用中使用的状态的集中存储,并通过规则确保状态只能以可预测的方式更新。
¥Redux is a pattern and library for managing and updating application state, using events called "actions". It serves as a centralized store for state that needs to be used across your entire application, with rules ensuring that the state can only be updated in a predictable fashion.
为什么我应该使用 Redux?
¥Why Should I Use Redux?
Redux 帮助你管理 "global" 状态 - 说明应用的许多部分都需要这一点。
¥Redux helps you manage "global" state - state that is needed across many parts of your application.
Redux 提供的模式和工具使你可以更轻松地了解应用中的状态何时、何地、为何以及如何更新,以及发生这些更改时应用逻辑的行为方式。Redux 指导你编写可预测和可测试的代码,这有助于让你确信你的应用将按预期工作。
¥The patterns and tools provided by Redux make it easier to understand when, where, why, and how the state in your application is being updated, and how your application logic will behave when those changes occur. Redux guides you towards writing code that is predictable and testable, which helps give you confidence that your application will work as expected.
我什么时候应该使用 Redux?
¥When Should I Use Redux?
Redux 可帮助你处理共享状态管理,但与任何工具一样,它也有权衡。有更多的概念需要学习,还有更多的代码需要编写。它还为你的代码添加了一些间接性,并要求你遵循某些限制。这是短期和长期生产力之间的权衡。
¥Redux helps you deal with shared state management, but like any tool, it has tradeoffs. There are more concepts to learn, and more code to write. It also adds some indirection to your code, and asks you to follow certain restrictions. It's a trade-off between short term and long term productivity.
Redux 在以下情况下更有用:
¥Redux is more useful when:
你拥有应用中许多地方都需要的大量应用状态
¥You have large amounts of application state that are needed in many places in the app
应用状态随着时间的推移频繁更新
¥The app state is updated frequently over time
更新该状态的逻辑可能很复杂
¥The logic to update that state may be complex
该应用具有中型或大型代码库,并且可能由很多人使用
¥The app has a medium or large-sized codebase, and might be worked on by many people
并非所有应用都需要 Redux。花一些时间考虑你正在构建的应用类型,并确定哪些工具最适合帮助解决你正在处理的问题。
¥Not all apps need Redux. Take some time to think about the kind of app you're building, and decide what tools would be best to help solve the problems you're working on.
如果你不确定 Redux 是否适合你的应用,这些资源会提供更多指导:
¥If you're not sure whether Redux is a good choice for your app, these resources give some more guidance:
Redux 库和工具
¥Redux Libraries and Tools
Redux 是一个小型独立 JS 库。但是,它通常与其他几个包一起使用:
¥Redux is a small standalone JS library. However, it is commonly used with several other packages:
React-Redux
Redux 可以与任何 UI 框架集成,并且最常与 React 一起使用。React-Redux 是我们的官方包,可让你的 React 组件通过读取状态片段并分派操作来更新存储来与 Redux 存储进行交互。
¥Redux can integrate with any UI framework, and is most frequently used with React. React-Redux is our official package that lets your React components interact with a Redux store by reading pieces of state and dispatching actions to update the store.
Redux 工具包
¥Redux Toolkit
Redux 工具包 是我们推荐的编写 Redux 逻辑的方法。它包含我们认为构建 Redux 应用所必需的包和函数。Redux Toolkit 构建了我们建议的最佳实践,简化了大多数 Redux 任务,防止常见错误,并使编写 Redux 应用变得更加容易。
¥Redux Toolkit is our recommended approach for writing Redux logic. It contains packages and functions that we think are essential for building a Redux app. Redux Toolkit builds in our suggested best practices, simplifies most Redux tasks, prevents common mistakes, and makes it easier to write Redux applications.
Redux DevTools 扩展
¥Redux DevTools Extension
Redux DevTools 扩展 显示 Redux 存储中状态随时间变化的历史记录。这使你可以有效地调试应用,包括使用 "时间旅行调试" 等强大的技术。
¥The Redux DevTools Extension shows a history of the changes to the state in your Redux store over time. This allows you to debug your applications effectively, including using powerful techniques like "time-travel debugging".
Redux 术语和概念
¥Redux Terms and Concepts
在深入研究实际代码之前,让我们先讨论一下使用 Redux 时需要了解的一些术语和概念。
¥Before we dive into some actual code, let's talk about some of the terms and concepts you'll need to know to use Redux.
状态管理
¥State Management
让我们首先看一个小型 React 计数器组件。它跟踪组件状态中的数字,并在单击按钮时增加该数字:
¥Let's start by looking at a small React counter component. It tracks a number in component state, and increments the number when a button is clicked:
function Counter() {
// State: a counter value
const [counter, setCounter] = useState(0)
// Action: code that causes an update to the state when something happens
const increment = () => {
setCounter(prevCounter => prevCounter + 1)
}
// View: the UI definition
return (
<div>
Value: {counter} <button onClick={increment}>Increment</button>
</div>
)
}
它是一个独立的应用,包含以下部分:
¥It is a self-contained app with the following parts:
状态,驱动我们应用的真相来源;
¥The state, the source of truth that drives our app;
视图,基于当前状态的 UI 声明性描述
¥The view, a declarative description of the UI based on the current state
应用中基于用户输入发生的操作、事件以及触发状态更新
¥The actions, the events that occur in the app based on user input, and trigger updates in the state
这是 "单向数据流" 的一个小例子:
¥This is a small example of "one-way data flow":
状态描述了应用在特定时间点的状况
¥State describes the condition of the app at a specific point in time
UI 根据该状态渲染
¥The UI is rendered based on that state
当发生某些事情时(例如用户单击按钮),状态会根据发生的情况进行更新
¥When something happens (such as a user clicking a button), the state is updated based on what occurred
UI 根据新状态重新渲染
¥The UI re-renders based on the new state
但是,当我们有多个需要共享和使用相同状态的组件时,特别是当这些组件位于应用的不同部分时,这种简单性可能会被打破。有时这可以通过 "提升状态" 到父组件来解决,但这并不总是有帮助。
¥However, the simplicity can break down when we have multiple components that need to share and use the same state, especially if those components are located in different parts of the application. Sometimes this can be solved by "lifting state up" to parent components, but that doesn't always help.
解决此问题的一种方法是从组件中提取共享状态,并将其放入组件树外部的集中位置。这样,我们的组件树就变成了一个大 "view",任何组件都可以访问状态或触发操作,无论它们位于树中的哪个位置!
¥One way to solve this is to extract the shared state from the components, and put it into a centralized location outside the component tree. With this, our component tree becomes a big "view", and any component can access the state or trigger actions, no matter where they are in the tree!
通过定义和分离状态管理中涉及的概念以及执行维护视图和状态之间独立性的规则,我们为代码提供了更多的结构和可维护性。
¥By defining and separating the concepts involved in state management and enforcing rules that maintain independence between views and states, we give our code more structure and maintainability.
这是 Redux 背后的基本思想:一个集中的位置,用于包含应用中的全局状态,以及更新该状态以使代码可预测时要遵循的特定模式。
¥This is the basic idea behind Redux: a single centralized place to contain the global state in your application, and specific patterns to follow when updating that state to make the code predictable.
不可变性
¥Immutability
"可变的" 表示 "changeable"。如果某件事是 "immutable",它就永远无法改变。
¥"Mutable" means "changeable". If something is "immutable", it can never be changed.
默认情况下,JavaScript 对象和数组都是可变的。如果我创建一个对象,我可以更改其字段的内容。如果我创建一个数组,我也可以更改内容:
¥JavaScript objects and arrays are all mutable by default. If I create an object, I can change the contents of its fields. If I create an array, I can change the contents as well:
const obj = { a: 1, b: 2 }
// still the same object outside, but the contents have changed
obj.b = 3
const arr = ['a', 'b']
// In the same way, we can change the contents of this array
arr.push('c')
arr[1] = 'd'
这称为改变对象或数组。它是内存中相同的对象或数组引用,但现在对象内部的内容已更改。
¥This is called mutating the object or array. It's the same object or array reference in memory, but now the contents inside the object have changed.
为了不可变地更新值,你的代码必须复制现有对象/数组,然后修改副本。
¥In order to update values immutably, your code must make copies of existing objects/arrays, and then modify the copies.
我们可以使用 JavaScript 的数组/对象扩展运算符以及返回数组新副本而不是改变原始数组的数组方法来手动完成此操作:
¥We can do this by hand using JavaScript's array / object spread operators, as well as array methods that return new copies of the array instead of mutating the original array:
const obj = {
a: {
// To safely update obj.a.c, we have to copy each piece
c: 3
},
b: 2
}
const obj2 = {
// copy obj
...obj,
// overwrite a
a: {
// copy obj.a
...obj.a,
// overwrite c
c: 42
}
}
const arr = ['a', 'b']
// Create a new copy of arr, with "c" appended to the end
const arr2 = arr.concat('c')
// or, we can make a copy of the original array:
const arr3 = arr.slice()
// and mutate the copy:
arr3.push('c')
Redux 期望所有状态更新都是不可变地完成的。稍后我们将了解这一点在何处以及如何重要,以及一些编写不可变更新逻辑的更简单的方法。
¥Redux expects that all state updates are done immutably. We'll look at where and how this is important a bit later, as well as some easier ways to write immutable update logic.
有关 JavaScript 中不可变性如何工作的更多信息,请参阅:
¥For more info on how immutability works in JavaScript, see:
术语
¥Terminology
在我们继续之前,你需要熟悉一些重要的 Redux 术语:
¥There are some important Redux terms that you'll need to be familiar with before we continue:
行动
¥Actions
操作是一个具有 type
字段的纯 JavaScript 对象。你可以将操作视为描述应用中发生的事情的事件。
¥An action is a plain JavaScript object that has a type
field. You can think of an action as an event that describes something that happened in the application.
type
字段应该是一个字符串,为该操作提供一个描述性名称,例如 "todos/todoAdded"
。我们通常会写像 "domain/eventName"
这样的类型字符串,其中第一部分是这个动作所属的特性或类别,第二部分是发生的具体事情。
¥The type
field should be a string that gives this action a descriptive name, like "todos/todoAdded"
. We usually write that type string like "domain/eventName"
, where the first part is the feature or category that this action belongs to, and the second part is the specific thing that happened.
操作对象可以包含其他字段,其中包含有关所发生事件的附加信息。按照惯例,我们将该信息放在名为 payload
的字段中。
¥An action object can have other fields with additional information about what happened. By convention, we put that information in a field called payload
.
典型的操作对象可能如下所示:
¥A typical action object might look like this:
const addTodoAction = {
type: 'todos/todoAdded',
payload: 'Buy milk'
}
动作创作者
¥Action Creators
动作创建者是一个创建并返回动作对象的函数。我们通常使用它们,这样我们就不必每次都手动编写操作对象:
¥An action creator is a function that creates and returns an action object. We typically use these so we don't have to write the action object by hand every time:
const addTodo = text => {
return {
type: 'todos/todoAdded',
payload: text
}
}
Reducer
reducer 是一个函数,它接收当前的 state
和 action
对象,决定如何在必要时更新状态,并返回新状态:(state, action) => newState
。你可以将 reducer 视为事件监听器,它根据接收到的操作(事件)类型来处理事件。
¥A reducer is a function that receives the current state
and an action
object, decides how to update the state if necessary, and returns the new state: (state, action) => newState
. You can think of a reducer as an event listener which handles events based on the received action (event) type.
"reducer" 函数之所以得名,是因为它们类似于传递给 Array.reduce()
方法的回调函数。
¥"Reducer" functions get their name because they're similar to the kind of callback function you pass to the Array.reduce()
method.
reducer 必须始终遵循一些特定的规则:
¥Reducers must always follow some specific rules:
他们应该只根据
state
和action
参数计算新的状态值¥They should only calculate the new state value based on the
state
andaction
arguments他们不得修改现有的
state
。相反,他们必须通过复制现有的state
并对复制的值进行更改来进行不可变的更新。¥They are not allowed to modify the existing
state
. Instead, they must make immutable updates, by copying the existingstate
and making changes to the copied values.它们不得执行任何异步逻辑、计算随机值或导致其他 "副作用"
¥They must not do any asynchronous logic, calculate random values, or cause other "side effects"
稍后我们将更多地讨论 reducer 的规则,包括它们为何重要以及如何正确遵循它们。
¥We'll talk more about the rules of reducers later, including why they're important and how to follow them correctly.
reducer 函数内部的逻辑通常遵循相同的一系列步骤:
¥The logic inside reducer functions typically follows the same series of steps:
检查 reducer 是否关心这个 action
¥Check to see if the reducer cares about this action
如果是,则复制状态,用新值更新副本,然后返回
¥If so, make a copy of the state, update the copy with new values, and return it
否则,返回现有状态不变
¥Otherwise, return the existing state unchanged
这是一个 reducer 的小示例,显示了每个 reducer 应遵循的步骤:
¥Here's a small example of a reducer, showing the steps that each reducer should follow:
const initialState = { value: 0 }
function counterReducer(state = initialState, action) {
// Check to see if the reducer cares about this action
if (action.type === 'counter/increment') {
// If so, make a copy of `state`
return {
...state,
// and update the copy with the new value
value: state.value + 1
}
}
// otherwise return the existing state unchanged
return state
}
reducer 可以使用内部任何类型的逻辑来决定新状态应该是什么:if/else
、switch
、循环等等。
¥Reducers can use any kind of logic inside to decide what the new state should be: if/else
, switch
, loops, and so on.
Detailed Explanation: Why Are They Called 'Reducers?'
Array.reduce()
方法允许你获取一个值数组,一次处理数组中的每一项,并返回一个最终结果。你可以把它想象成 "将数组减少到一个值"。
¥The Array.reduce()
method lets you take an array of values, process each item in the array one at a time, and return a single final result. You can think of it as "reducing the array down to one value".
Array.reduce()
采用回调函数作为参数,该函数将为数组中的每一项调用一次。它需要两个参数:
¥Array.reduce()
takes a callback function as an argument, which will be called one time for each item in the array. It takes two arguments:
previousResult
,你上次回调返回的值¥
previousResult
, the value that your callback returned last timecurrentItem
,数组中的当前项¥
currentItem
, the current item in the array
回调第一次运行时,没有可用的 previousResult
,因此我们还需要传入一个初始值,该值将用作第一个 previousResult
。
¥The first time that the callback runs, there isn't a previousResult
available, so we need to also pass in an initial value that will be used as the first previousResult
.
如果我们想将一组数字相加来找出总数,我们可以编写一个如下所示的 reduce 回调:
¥If we wanted to add together an array of numbers to find out what the total is, we could write a reduce callback that looks like this:
const numbers = [2, 5, 8]
const addNumbers = (previousResult, currentItem) => {
console.log({ previousResult, currentItem })
return previousResult + currentItem
}
const initialValue = 0
const total = numbers.reduce(addNumbers, initialValue)
// {previousResult: 0, currentItem: 2}
// {previousResult: 2, currentItem: 5}
// {previousResult: 7, currentItem: 8}
console.log(total)
// 15
请注意,这个 addNumbers
"减少回调" 函数本身不需要跟踪任何内容。它接受 previousResult
和 currentItem
参数,对它们执行某些操作,然后返回一个新的结果值。
¥Notice that this addNumbers
"reduce callback" function doesn't need to keep track of anything itself. It takes the previousResult
and currentItem
arguments, does something with them, and returns a new result value.
Redux reducer 函数与这个 "减少回调" 函数的想法完全相同!它采用 "之前的结果"(state
)和 "当前项目"(action
对象),根据这些参数决定新的状态值,并返回该新状态。
¥A Redux reducer function is exactly the same idea as this "reduce callback" function! It takes a "previous result" (the state
), and the "current item" (the action
object), decides a new state value based on those arguments, and returns that new state.
如果我们要创建一个 Redux actions 数组,调用 reduce()
,并传入一个 reducer 函数,我们会以同样的方式得到最终结果:
¥If we were to create an array of Redux actions, call reduce()
, and pass in a reducer function, we'd get a final result the same way:
const actions = [
{ type: 'counter/increment' },
{ type: 'counter/increment' },
{ type: 'counter/increment' }
]
const initialState = { value: 0 }
const finalResult = actions.reduce(counterReducer, initialState)
console.log(finalResult)
// {value: 3}
我们可以说 Redux reducer 将一组操作(随着时间的推移)减少为单个状态。不同之处在于,对于 Array.reduce()
,它会同时发生,而对于 Redux,它会在正在运行的应用的生命周期内发生。
¥We can say that Redux reducers reduce a set of actions (over time) into a single state. The difference is that with Array.reduce()
it happens all at once, and with Redux, it happens over the lifetime of your running app.
存储
¥Store
当前的 Redux 应用状态位于一个名为 store 的对象中。
¥The current Redux application state lives in an object called the store .
store 是通过传入一个 reducer 来创建的,并且有一个名为 getState
的方法,该方法返回当前状态值:
¥The store is created by passing in a reducer, and has a method called getState
that returns the current state value:
import { configureStore } from '@reduxjs/toolkit'
const store = configureStore({ reducer: counterReducer })
console.log(store.getState())
// {value: 0}
派遣
¥Dispatch
Redux 存储有一个名为 dispatch
的方法。更新状态的唯一方法是调用 store.dispatch()
并传入一个操作对象。store 将运行它的 reducer 函数并将新的状态值保存在里面,我们可以调用 getState()
来检索更新后的值:
¥The Redux store has a method called dispatch
. The only way to update the state is to call store.dispatch()
and pass in an action object. The store will run its reducer function and save the new state value inside, and we can call getState()
to retrieve the updated value:
store.dispatch({ type: 'counter/increment' })
console.log(store.getState())
// {value: 1}
你可以将应用中的调度操作视为 "触发事件"。发生了一些事情,我们希望存储知道这件事。reducer 就像事件监听器一样,当它们听到感兴趣的操作时,它们会更新状态作为响应。
¥You can think of dispatching actions as "triggering an event" in the application. Something happened, and we want the store to know about it. Reducers act like event listeners, and when they hear an action they are interested in, they update the state in response.
我们通常调用动作创建者来调度正确的动作:
¥We typically call action creators to dispatch the right action:
const increment = () => {
return {
type: 'counter/increment'
}
}
store.dispatch(increment())
console.log(store.getState())
// {value: 2}
选择器
¥Selectors
选择器是知道如何从存储状态值中提取特定信息的函数。随着应用变得越来越大,这可以帮助避免重复逻辑,因为应用的不同部分需要读取相同的数据:
¥Selectors are functions that know how to extract specific pieces of information from a store state value. As an application grows bigger, this can help avoid repeating logic as different parts of the app need to read the same data:
const selectCounterValue = state => state.value
const currentValue = selectCounterValue(store.getState())
console.log(currentValue)
// 2
Redux 应用数据流
¥Redux Application Data Flow
之前,我们讨论了 "单向数据流",它描述了更新应用的步骤顺序:
¥Earlier, we talked about "one-way data flow", which describes this sequence of steps to update the app:
状态描述了应用在特定时间点的状况
¥State describes the condition of the app at a specific point in time
UI 根据该状态渲染
¥The UI is rendered based on that state
当发生某些事情时(例如用户单击按钮),状态会根据发生的情况进行更新
¥When something happens (such as a user clicking a button), the state is updated based on what occurred
UI 根据新状态重新渲染
¥The UI re-renders based on the new state
特别是对于 Redux,我们可以将这些步骤分解为更详细的内容:
¥For Redux specifically, we can break these steps into more detail:
初始设置:
¥Initial setup:
Redux 存储是使用根 reducer 函数创建的
¥A Redux store is created using a root reducer function
store 调用一次根 reducer,并将返回值保存为其初始
state
¥The store calls the root reducer once, and saves the return value as its initial
state
当 UI 首次渲染时,UI 组件访问 Redux 存储的当前状态,并使用该数据来决定渲染什么。他们还订阅任何未来的存储更新,以便他们知道状态是否发生变化。
¥When the UI is first rendered, UI components access the current state of the Redux store, and use that data to decide what to render. They also subscribe to any future store updates so they can know if the state has changed.
更新:
¥Updates:
应用中发生了一些事情,例如用户单击按钮
¥Something happens in the app, such as a user clicking a button
应用代码将一个操作分派到 Redux 存储,例如
dispatch({type: 'counter/increment'})
¥The app code dispatches an action to the Redux store, like
dispatch({type: 'counter/increment'})
store 用之前的
state
和当前的action
再次运行 reducer 函数,并将返回值保存为新的state
¥The store runs the reducer function again with the previous
state
and the currentaction
, and saves the return value as the newstate
存储通知订阅的 UI 的所有部分该存储已更新
¥The store notifies all parts of the UI that are subscribed that the store has been updated
每个需要存储中数据的 UI 组件都会检查它们所需的状态部分是否已更改。
¥Each UI component that needs data from the store checks to see if the parts of the state they need have changed.
每个看到其数据已更改的组件都会强制使用新数据重新渲染,因此它可以更新屏幕上显示的内容
¥Each component that sees its data has changed forces a re-render with the new data, so it can update what's shown on the screen
数据流的视觉效果如下:
¥Here's what that data flow looks like visually:
你学到了什么
¥What You've Learned
Redux 确实有许多新术语和概念需要记住。提醒一下,这是我们刚刚介绍的内容:
¥Redux does have a number of new terms and concepts to remember. As a reminder, here's what we just covered:
Redux 是一个用于管理全局应用状态的库
¥Redux is a library for managing global application state
Redux 通常与 React-Redux 库一起使用,将 Redux 和 React 集成在一起
¥Redux is typically used with the React-Redux library for integrating Redux and React together
Redux Toolkit 是编写 Redux 逻辑的推荐方式
¥Redux Toolkit is the recommended way to write Redux logic
Redux 使用 "单向数据流" 应用结构
¥Redux uses a "one-way data flow" app structure
状态描述了应用在某个时间点的状况,UI 根据该状态进行渲染
¥State describes the condition of the app at a point in time, and UI renders based on that state
当应用中发生某些情况时:
¥When something happens in the app:
UI 调度一个动作
¥The UI dispatches an action
存储运行 reducer,并根据发生的情况更新状态
¥The store runs the reducers, and the state is updated based on what occurred
存储通知 UI 状态已更改
¥The store notifies the UI that the state has changed
UI 根据新状态重新渲染
¥The UI re-renders based on the new state
Redux 使用多种类型的代码
¥Redux uses several types of code
操作是带有
type
字段的普通对象,并在应用中描述 "发生了什么"¥Actions are plain objects with a
type
field, and describe "what happened" in the appreducer 是根据先前状态+操作计算新状态值的函数
¥Reducers are functions that calculate a new state value based on previous state + an action
每当调度操作时,Redux 存储都会运行根 reducer
¥A Redux store runs the root reducer whenever an action is dispatched
下一步是什么?
¥What's Next?
我们已经了解了 Redux 应用的每个单独部分。接下来,继续进行 第 2 部分:Redux 工具包应用结构,我们将查看一个完整的工作示例,以了解各个部分如何组合在一起。
¥We've seen each of the individual pieces of a Redux app. Next, continue on to Part 2: Redux Toolkit App Structure, where we'll look at a full working example to see how the pieces fit together.