Redux 概述
在使用 react 框架对组件进行状态管理的时候常常会遇到一些不方便的情况,特别是一些全局需要用到的状态,这时候常用的解决方案是使用 redux。本文会结合 react 介绍 redux。
React 的状态管理
首先要说的是 react 的一个基本思路,作为一个纯 view 层框架,react 遵循了view = fn(state)的一个概念,即组件是一个函数,将状态传给组件,则会通过状态输出一个 view。
一个组件通过传入的初始状态生成初始的 view。这时使用者想要主动改变一个状态的时候,就需要在 view 层主动声明一个方法,例如onChange={this.handleValueChange},然后方法通过调用setState来更新数据,数据更新完再通过fn(newState)来生成新的 view。
在实际使用中情况其实并没有这么简单,跨组件更新 state 的情况就会经常遇到:如果是子组件需要更新父组件的状态,需要使用this.props.handleValueChange方法,如果是父组件想要更新子组件的状态需要使用refs。这些都是最简单情况。
然而如果遇到像登录状态这样的需要很多个组件同时调用、甚至有时候更改需要触发一些组件相应动作的数据,如果使用最基础的解决方法,实现的效率就会非常麻烦:
首先我们要考虑这个状态存在哪:
- 它不可能存在一个比较低级的组件中,这样组件之间调用起来相当麻烦;
- 如果存在一个比较高级的组件里,如果想获取,则要通过多层的 props 来传递;
- 可以让低级组件通过 context 来获取,然而由于 context API 相对繁琐,这么做的开发效率会变得很低(实际上 redux 内部使用的是这个方法,另外新版 react 的 context API 变得相对简单,调用起来跟 redux 类似);
- 如果高级组件和低级组件中各保存一份状态,那么每次更新想要保证各个组件中的状态一致性又是一个让人头疼的问题。
这就使问题变得比较难办,我们需要一个方便各级组件调用、容易协调状态、实现简单的解决工具来帮助我们管理状态,这时 redux 就横空出世了。
Redux 的实现思路
上面已经明确了 redux 要解决的痛处。 第一点上面已经说过了,redux 通过使用 React 的 context API 来实现父组件跨级向子组件传输状态,然后封装成一个 HOC 方便我们使用。
单一 store
如果要方便协调数据,肯定不能把数据存放在分散的各个角落,因此要确保数据是存在单一的 store 中。另外,由于 react 遵循的view = fn(state)概念,这个 store 最好是要拥有初始状态(initState)的。
我们把所需要的数据都存放在单一的 store 中,再由这个 store 向各个组件分发数据。当组件想要改变 store 的中的状态时,在通过相应的方法提交状态更新。这个概念是 flux 框架的简单理解,而更新状态和分发数据的概念称为单向数据流。
单向数据流
为了方便管理和分发 state(可以理解为存在 store 中的数据),我们先把 state 存在一个 store 中,再把 state 作为组件的 props 分发下去,组件再通过这些 props 生成 view。当某个组件要更新 store 中数据的时候,通过dispatch方法将要改变的地方提交给 reducer ;reducer 通过计算,返回一个新的 state,替换 store 中的 oldState;然后进入一个新的循环。