React-Redux 学习笔记

104 阅读5分钟

首先从什么是Redux入手 Redux是一个独立的库(library),可以和UI框架(如React)结合使用,可以提供中心化的存储,用来管理和更新应用内的全局状态。

React-Redux是什么? 就像前面提到的,如果我们想把redux与UI框架结合使用,那么我们需要把它们绑定(bind)在一起。React-Redux就是一个提供这种功能的官方库(library)。在实际使用中,这两种库要被一起引入。

在什么场景下应该使用Redux?(场景按照权重排序)

  • 存在需要全局共享的状态
  • 状态的更新逻辑复杂
  • 状态需要经常更新(react-state也可以做到)

Redux对比React-State

  • State无法优雅的做到全局共享状态。只能通过将所有的状态提升至根component来实现,这样会导致很多复杂的透传、回调函数的交叉使用等等。
  • State在组件卸载之后就会消失
  • setState回调函数的相互传递会导致组件逻辑复杂
  • Redux管理的组件一般来说比State管理的更加易于测试

组成: 一个基本的Redux状态管理系统大致需要以下几个组件构成:

  1. Store:本质上是一个JS的对象,用于存放所有的全局状态。这里注意,store里面的状态值(value)不允许直接被修改,而是应该使用官方提供的使用action-reducer的修改流程。这里的原因主要是因为全局状态本身就可以很复杂,难以debug,如果允许直接修改的话会导致很多意外。
  2. Action:也是一个JS对象,主要用来描述‘什么发生了’。它本身有一个‘type’字段用于简短的描述发生了什么事件,以及经常被添加‘payload’字段用来携带附加信息。
  3. Reducer:是一个函数,它接收两个参数,目前的‘state’和‘action’。然后根据action类型和设计好的逻辑返回更新之后的state。
  4. dispatch和selector。两个用于更新和读取state的函数。其中,dispatch函数以action对象为参数,执行时会发出action用于更新state,selector用来读取state里面特定的状态值

Redux状态的基本修改流程 Redux data flow diagram

  1. UI组件由于用户的输入/交互产生了一个event
  2. event会trigger对应的event handler,从而dispatch了一个预设的带有描述信息的action
  3. action被reducer捕获,reducer根据action的内容和当前state的状态按照预设的逻辑进行处理,之后返回更新后的state
  4. state更新后通知UI组件也进行同步更新

Redux的三大核心概念:

  1. 单一信息源:全局状态只应该存在于一个单一的store,任何单一的数据片段都不应该复制并存在于多个不同的地方。这里主要是为了方便debug,如果同一个数据片段/状态存在于多个不同的位置,那么就会出现‘到底那份数据是可信的’、‘我应该更新哪份数据?’、‘我应该订阅哪份数据’这样的问题。
  2. State是只读的:State仅允许使用‘action-reducer’流程来更新,不允许直接使用对象方法进行更新
  3. Reducer必须是纯函数:reducer函数在相同的输入情况下应该具有相同的输出。这意味着,reducer不应该自身进行某种存储来影响输出。

项目上的实践:

  1. 前面提及的’单一信息源‘概念不应该狭义的理解为‘每个数据片段只允许在store出现一次’。这里的‘数据片段’并不只是指单个数据(例如:{age: number}),也可以指对应于某个UI组件的,打包好的数据。举个例子,组件A需要存储并读取状态details: {name: string, age: number},同时组件B仅需要读取状态details:{name: string, age: number}那么此时我们可以认为A,B两组件所依赖的状态不是同一个状态。B所依赖的状态的来源是A所依赖的状态。每次,当A对应的状态dispatch了action要求更新的时候,B对应的reducer也会对自己的状态进行同步监听,同步更改。并且一般认为,对数据拥有改动权限的组件是数据的所有者。
  2. 一般来说组件的state不易被直接测试到,而如果使用了redux,那么所有的状态管理将会从组件内部转移到外部,并且组件通过props来接收对应的状态。这个无论是从职责分离角度还是易于测试角度都是优势。
  3. Redux的’发布-订阅‘模式可以提供更好的独立性(解耦)。当需要更新状态时,需求发出方只需要dispatch一个对应的action,它不关心谁去订阅这个action。以及将来如果需要增减订阅方也会由于这种独立性变得简单。
  4. fetch来的并且需要长久保存的需要影响UI的数据,一般流程是通过action将其存储在state里面,之后借用state更新通知UI组件更新的机制更新UI

参考: redux.js.org/tutorials/f…