首先从什么是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状态管理系统大致需要以下几个组件构成:
- Store:本质上是一个JS的对象,用于存放所有的全局状态。这里注意,store里面的状态值(value)不允许直接被修改,而是应该使用官方提供的使用action-reducer的修改流程。这里的原因主要是因为全局状态本身就可以很复杂,难以debug,如果允许直接修改的话会导致很多意外。
- Action:也是一个JS对象,主要用来描述‘什么发生了’。它本身有一个‘type’字段用于简短的描述发生了什么事件,以及经常被添加‘payload’字段用来携带附加信息。
- Reducer:是一个函数,它接收两个参数,目前的‘state’和‘action’。然后根据action类型和设计好的逻辑返回更新之后的state。
- dispatch和selector。两个用于更新和读取state的函数。其中,dispatch函数以action对象为参数,执行时会发出action用于更新state,selector用来读取state里面特定的状态值
Redux状态的基本修改流程
- UI组件由于用户的输入/交互产生了一个event
- event会trigger对应的event handler,从而dispatch了一个预设的带有描述信息的action
- action被reducer捕获,reducer根据action的内容和当前state的状态按照预设的逻辑进行处理,之后返回更新后的state
- state更新后通知UI组件也进行同步更新
Redux的三大核心概念:
- 单一信息源:全局状态只应该存在于一个单一的store,任何单一的数据片段都不应该复制并存在于多个不同的地方。这里主要是为了方便debug,如果同一个数据片段/状态存在于多个不同的位置,那么就会出现‘到底那份数据是可信的’、‘我应该更新哪份数据?’、‘我应该订阅哪份数据’这样的问题。
- State是只读的:State仅允许使用‘action-reducer’流程来更新,不允许直接使用对象方法进行更新
- Reducer必须是纯函数:reducer函数在相同的输入情况下应该具有相同的输出。这意味着,reducer不应该自身进行某种存储来影响输出。
项目上的实践:
- 前面提及的’单一信息源‘概念不应该狭义的理解为‘每个数据片段只允许在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也会对自己的状态进行同步监听,同步更改。并且一般认为,对数据拥有改动权限的组件是数据的所有者。 - 一般来说组件的state不易被直接测试到,而如果使用了redux,那么所有的状态管理将会从组件内部转移到外部,并且组件通过props来接收对应的状态。这个无论是从职责分离角度还是易于测试角度都是优势。
- Redux的’发布-订阅‘模式可以提供更好的独立性(解耦)。当需要更新状态时,需求发出方只需要dispatch一个对应的action,它不关心谁去订阅这个action。以及将来如果需要增减订阅方也会由于这种独立性变得简单。
- fetch来的并且需要长久保存的需要影响UI的数据,一般流程是通过action将其存储在state里面,之后借用state更新通知UI组件更新的机制更新UI