Redux是什么? 和React有什么联系?
00 分钟
2022-2-23
2023-7-20
category
tags
type
status
slug
date
summary
icon
password
 

一、Redux和React 有什么联系?

首先:Redux 和 React 之间并没有强制关联。
Redux 可以搭配 React、Angular 甚至纯 JS。不过 Redux 比较适合和 React 搭配,因为 React 允许你以 state 的形式来描述界面,而 Redux 非常擅长控制 state 的变化

我该用Redux吗?

Redux 的创造者 Dan Abramov 曾说过:"只有遇到 React 实在解决不了的问题,你才需要 Redux 。"
如果你的UI层非常简单,没有很多互动,Redux 就是不必要的,用了反而增加复杂性。
事实上,在React 16.8中已经引入了的新 API useContext 和 useReducer ,完全可以用来取代Redux的功能。详情参考此文:用 useContext + useReducer 替代 redux

二、从React看Redux

Redux是什么?解答这个问题并不困难,前提是你熟悉React。仅听别人描述名词,理解起来还是很困难的,我们从根本需求出发,看看使用React需要什么:

1.自上向下的数据流

React有propsstate
props意味着父级分发下来的属性,state意味着组件内部可以自行管理的状态。
整个React没有数据向上回溯的能力,子组件不能直接修改父组件的数据,也就是说数据只能单向向下分发,或者自行内部消化。

举个例子

假设有一个 ParentComponent 父组件和一个 ChildComponent 子组件,其中父组件有一个状态 count,子组件需要显示这个状态。
  • 父组件:
    • 子组件:
      在这个示例代码中,父组件 ParentComponent 中包含一个状态 count 和一个函数 incrementCount,用于增加 count 的值。子组件 ChildComponent 中通过 props 接收来自父组件的 count 值,并将其显示出来。
      当用户在父组件中点击 Increment count 按钮时,会触发 incrementCount 函数,该函数会更新状态 count 的值。因为子组件中的 count 值是通过 props 从父组件中传递下来的,所以子组件中的 count 值也会随之更新,并重新渲染显示最新的 count 值。
      在这个示例代码中,数据从父组件 ParentComponent 流向子组件 ChildComponent,子组件不能直接修改父组件的数据,只能通过 props 接收来自父组件的数据并显示出来。这就是 React 的单向数据流。
      理解这个是理解React和Redux的前提。

      2.组件间的交互

      一般构建的React组件内部可能是一个完整的应用,它自己工作良好,你可以通过属性作为API控制它。
      但是更多的时候发现React根本无法让两个组件互相交流,使用对方的数据。这时候不通过DOM通讯(仅使用React自身特性进行通讯)解决的唯一办法就是提升state,将state放到共有的父组件中来管理,再作为props分发回子组件。

      3.子组件改变父组件

      子组件改变父组件state的办法只能是通过onClick触发父组件声明好的回调,也就是父组件提前声明好函数或方法作为契约描述自己的state将如何变化,再将它同样作为属性交给子组件使用。

      举个例子

      • 创建ChildComponent,我们通过props可以取到从父组件传进来的属性,例如我们约定当这个组件被点击时,会调用组件的onMessage属性参数
        • 创建一个组件ParentComponent,并在其中套用子组件ChildComponent,并在<ChildComponent/>组件中,添加一个onMessage属性参数绑定您的函数方法,即可监听子组件的事件传递。(代码中的加粗部分)
          上面这个例子中,onMessage被称之为回调参数,这是子组件向其他父组件的约定。在上层组件中将此回调参数绑定在了 handleMessage这个父级方法上。而回调过传递的message就是要通讯的状态值
          这样就出现了一个模式:数据总是单向从顶层向下分发的,只有子组件通过回调绑定才可以影响到顶层数据

          4. 解决扩展问题

          在实际开发中 ,很可能面临很多扩展问题,例如一个组件需要通知其它组件各式各样的事件函数、甚至要夸多层级通讯,这时候使用回调参数声明的方式,维护就很困难了。
          最容易想到的办法就是把所有state集中起来,放到所有组件顶层,然后统一分发给所有组件。
          而为了有更好的state管理,就需要一个库来作为更专业的顶层state,负责分发给所有React应用,这就是Redux
           
          总的来说,要实现React上面的state管理,需要需要这样的三要素,他们分别对应redux中的三个名词action、reducer、store
          💡
          a. 需要回调通知state (等同于回调参数onMessage) -> action
          b. 需要根据回调处理 (等同于父级方法handleMessage) -> reducer
          c. 需要state (等同于总状态 message的useState) -> store

          二、Redux能提供什么

          Redux 是一个使用叫做“action”的事件来管理和更新应用状态的模式和工具库,它以集中式Store(centralized store)的方式对整个应用中使用的状态进行集中式的全局管理,其规则确保状态只能以可预测的方式更新。
          Redux 提供的模式和工具使您更容易理解应用程序中的状态何时、何地、为什么以及如何更新,以及当这些更改发生时您的应用程序逻辑将如何表现,Redux 指导您编写可预测和可测试的代码,这有助于让您确信您的应用程序将按预期工作。

          Redux三剑客

          Redux的三个核心元素:action、reducer、store,我在上面讨论React的需求时有提及到。

          1. action

          纯声明式的数据结构,只提供事件的所有要素,不提供逻辑。

          2. reducer

          一个匹配函数,action的发送是全局的:所有的reducer都可以捕捉到并匹配与自己相关与否,相关就拿走action中的要素进行逻辑处理,修改store中的状态,不相关就不对state做处理原样返回。

          3. store

          负责存储状态并可以被react api回调,发布action.

          Redux工作流程

          notion image
          1. 用户发出 Action。
            1. Store 自动调用 Reducer,并且传入两个参数:当前 State 和收到的 Action。 Reducer 会返回新的 State 。
              1. State 一旦有变化,Store 就会调用监听函数。
                1. listener可以通过store.getState()得到当前状态。如果使用的是 React,这时可以触发重新渲染 View。
                   

                  四、Redux-React库

                  实际情况中,在使用React框架时,我们会使用React-redux库。
                  Redux-React 是一个用于在 React 应用中使用 Redux 的库。它提供了一些用于连接 React 组件和 Redux store 的 API,使得在 React 应用中使用 Redux 变得更加简单和方便。下面将详细说明如何使用 Redux-React。
                  这其实类似于文章开头提到的:React 16.8中引入的新 API useContext 和 useReducer ,详情参考此文:用 useContext + useReducer 替代 redux

                  举个例子

                  1. 安装 Redux 和 React-Redux
                    1. 首先需要安装 Redux 和 React-Redux 两个库。可以使用以下命令进行安装:
                  1. 创建 Redux store
                    1. 在 React 应用中使用 Redux,首先需要创建一个 Redux store。可以使用 createStore 函数来创建一个 Redux store,例如:
                      在这个示例代码中,store 是通过调用 createStore 函数创建的,rootReducer 是一个 Redux reducer,用于处理 Redux store 中的状态更新。
                  1. 在 React 应用中使用 Redux-React
                    1. Redux-React 提供了 Provider 组件,可以将 Redux store 传递给 React 应用中的所有组件。可以在应用的根组件中使用 Provider 组件,例如:
                      在这个示例代码中,Provider 组件接收 store 作为 props,并将其传递给所有的子组件。App 组件是应用的根组件。
                  1. 连接 React 组件和 Redux store
                    1. 使用 Redux-React,可以将 Redux store 中的状态映射到 React 组件的 props 中,也可以将 React 组件中的事件映射到 Redux store 中的 action 中。可以使用 connect 函数来连接 React 组件和 Redux store,例如:
                  在这个示例代码中,Counter 组件使用 connect 函数连接到 Redux store 中。mapStateToProps 函数将 Redux store 中的状态映射到 Counter 组件的 props 中,mapDispatchToProps 函数将 Counter 组件中的事件映射到 Redux store 中的 action 中。
                  通过这种方式,可以在 Counter 组件中使用 Redux store 中的状态,并将事件触发后的状态更新传递给 Redux store。
                  以上就是使用 Redux-React 的基本步骤,通过将 Redux store 传递给 React 应用中的所有组件,以及使用 connect 函数连接 React 组件和 Redux store,可以在 React 应用中方便地使用 Redux。
                  connect是一个科里化函数,意思是先接受两个参数(数据绑定mapStateToProps和事件绑定mapDispatchToProps),再接受一个参数(将要绑定的组件本身)。

                  总结

                  做好以上流程Redux和React就可以工作了。简单地说Redux就是:
                  1.顶层分发状态,让React组件被动地渲染。
                  2.监听事件,事件有权利回到所有状态顶层影响状态。
                   

                  文章参考