状态管理之 Redux & React Redux

原文地址: https://monster1935.com/2019/...

在进行 React 技术栈的一些技术方案的「挖坟」过程当中,有这样一个体会:为何须要这样一个方案,是遇到了什么的问题,引入该方案会带来什么样的收益。任何技术方案的引入都对应了某些技术场景下遇到的问题。javascript

Vue 的开发中引入了状态管理方案 Vuex,Vuex 的引入可有效下降组件之间的通讯复杂度同时还提供了全局状态管理的能力,对于一个中大型平台来讲,引入状态管理方案势在必得。html

遇到的问题

讨论任何技术方案,都要从遇到的问题场景入手。在 Redux 的原做者 Dan Abramov
You Might Not Need Redux 一文中阐释了这个思想,是否是必定要用 Redux,不是的。什么场景下,什么问题下能够引用这个技术方案,是咱们在考虑一些技术方案选型落地时的必需要考虑的一个问题。java

咱们遇到了什么问题?react

Redux 中文文档「动机」一章中作了总结。大体有这么几个问题:git

  1. 中大型单页应用的开发中,随着应用复杂度的提高,状态愈来愈多
  2. 状态的更改场景愈来愈多,包括用户交互,异步请求,组件之间的通讯等
  3. 状态更改不可控,遇到问题很差排查

如何解决这些问题,就须要有一个统一的解决方案,最关键的一点:状态可控易管理github

显然,Redux 就是来作这些事情的。redux

从 Redux 的三大原则中咱们就能够看出来,Redux 就是完成状态的可控易管理。性能优化

1、 单一数据源(store)数据结构

整个应用的 state 被存储在一个 store 中,管理方便,对于服务端渲染有较大优点(就是你们常说的同构应用)。app

2、 state 只读

state 不能直接被修改,必须 dispatch action 去修改。一个 action 就是一个js对象,描述即将发生的事情和要携带的参数。这个原则保证了状态的修改可控

3、经过纯函数(pure function)去修改 state

纯函数有个特色,整个过程当中不产生任何反作用,固定的输入必产生固定的输出。此举保证了 state 变动的可追踪性。

以上,咱们也就理解了 redux 这个库在 github 上的介绍

Predictable state container for JavaScript apps
(一个为 js 应用而生的可预测的状态容器)

Redux 都作了什么

import { createStore } from 'redux'

function todos(state = [], action) {
  switch (action.type) {
    case 'ADD_TODO':
      return state.concat([action.text])
    default:
      return state
  }
}

let store = createStore(todos, ['Use Redux'])

store.dispatch({
  type: 'ADD_TODO',
  text: 'Read the docs'
});

store.subscribe(() => {
  // do your update
  console.log(store.getState())
})

如上所示,这是一个最简单的 Redux 的使用示例。主要作了这几件事情:

  1. 建立一个全局 store,注意 redux 是单一数据源思想,所以在一个应用中使用一个 store 便可
  2. store 中获取 state 经过 store.getState()
  3. 想要改变 state 经过 dispatch 一个 action, action 是一个用来描述此次动做的 js 对象,里面包含了 action 的 type 和 payload,这里能够衍生出 action creator 的概念,一个函数专门用来产生 action。
  4. 一个 reducer 专门负责更新 state,经过判断不一样的 action type,操做不一样的state返回。注意这里不要直接操做 state, 而是 clone 一份,而后返回一个全新的 state,此处能够衍生出一些其余的数据结构的操做方案,如 immutable 方案。

经过以上咱们能够发现,这是一个彻底解耦的状态管理方案,不依赖于其余的任何库,一个纯 javascript 实现。在这一点上,和 Vuex 有着本质上的区别。也就是说 Vuex 只能是在 Vue 的全家桶中使用,是一个上层的状态管理方案。Redux 不一样,它能够和任何 javascript 应用开发结合使用。那么在 React 中如何集成 Redux 呢,这就是接下来咱们要讨论的 React Redux。

React Redux

React Redux 是一个在 React 中使用 Redux 方案的库。为何引入一个状态管理方案,除了引入 Redux 还要引入 React Redux?

咱们须要从 React Redux 所作的事情入手。React Redux作了什么?

  1. 每一个组件均可以 dispatch action 更改 state
  2. 每一个组件都只拿本身关心的 props 进行渲染
  3. 每一个组件均可以获取全局的 store 实例
  4. 全局状态的更改的订阅,获取最新的 state
  5. 一些性能优化,避免一些没必要要的 re-render 过程

综上几点,咱们能够大体感知 React Redux 所作的一些事情,将一些通用的代码进行封装,暴露出 API 以简化在 React 中的使用。

有这么几个概念比较重要。

1、Provider

一个包含组件,接收 store 参数,子组件中均可以经过 connect 方法得到 store

2、connect()

一个高阶函数,返回一个 React 组件,主要作了如下两件事情:

  1. mapState,将 store 中 state 以 props 的形式传递给被 connect 的组件,
  2. mapDispatch,将 store 中的 action 以 props 的形式传递给被 connect 的组件,这其中还作了不少封装,能够容许咱们直接传递 action creator,在使用的时候省去 dispatch 的过程

总结

以上仅仅是一个针对 Redux 和 React Redux 的大体轮廓。这个过程当中还有几个问题没有讨论:

  1. Redux 中仅仅能够 dispatch 一个 action 去更新 state,如何将一些带反作用的过程进行封装,这就要讨论到 React 的中间件机制
  2. React Redux 中的性能优化都作了哪些事情

Redux 目前的维护者 Mark EriksonIdiomatic Redux: The History and Implementation of React Redux 一文中针对 React Redux 的 API 版本迭代过程当中进行了很透彻的分析,推荐。

参考连接

  1. https://www.redux.org.cn/docs...
  2. https://blog.isquaredsoftware...
  3. https://medium.com/@dan_abram...
相关文章
相关标签/搜索