Redux 主要知识点与数据流分析

11 April 2016

redux react redux-thunk

什么是Redux

每一个中间件的出现都是为了解决某个问题而来。redux 就是为了解决state的不可测而生,redux试图让state变得可预测。

Redux 的3大原则

1.单一数据源

所有的state都会被存放到一个object对象树中,并且object只存在于唯一一个state中

2. State是只读的

唯一能改变state的方法就是通过action触发,action 只是描述了有事情发生了这一事实,并没有指明应用如何更新 state–reducer才是。

3. reducer修改state

reducer就是一个函数,接收旧的 state 和 action,返回新的 state。

reducer 纯净非常重要。永远不要在 reducer 里做这些操作:

    1. 修改传入参数;
    1. 执行有副作用的操作,如 API 请求和路由跳转;
    1. 调用非纯函数,如 Date.now() 或 Math.random()。

Redux VS Flux

Flux:是Facebook用户建立客户端Web应用的前端架构, 它通过利用一个单向的数据流补充了React的组合视图组件,这更是一种模式而非正式框架,你能够无需许多新代码情况下立即开始使用Flux。

了解更多关于Fulx:

Flux应用框架

共同点:

    1. 将模型的更新逻辑全部集中于一个特定的层( Flux 里的 store,Redux 里的 reducer )
    1. Flux 和 Redux 都不允许程序直接修改数据,而是用一个叫作 “action” 的普通对象来对更改进行描述。

区别:

    1. Redux 并没有 dispatcher 的概念。原因是它依赖纯函数(reducer)来替代事件处理器.
    1. Redux 设想你永远不会变动你的数据

基础

1.Action

Action 只是描述了有事情发生了这一事实; 是把数据从应用传到 store 的有效载荷。它是 store 数据的唯一来源。一般来说你会通过 store.dispatch() 将 action 传到 store。

注意点:

    1. Action 本质上是 JavaScript 普通对象
    1. 约定,action 内使用一个字符串类型的 type 字段来表示将要执行的动作
    1. 尽量减少在 action 中传递的数据
    1. 创建函数 就是生成 action 的方法(注意:export 出去)

2.Reducer

指明应用如何更新 state。

  //reducer 就是一个函数,接收旧的 state 和 action,返回新的 state。
  (previousState, action) => newState

要点:

    1. 尽可能地把 state 范式化,不存在嵌套。把所有数据放到一个对象里,每个数据以 ID 为主键,不同数据相互引用时通过 ID 来查找.
    1. reducer 一定要保持纯净。只要传入参数一样,返回必须一样。没有特殊情况、没有副作用,没有 API 请求、没有修改参数,单纯执行计算.
    1. 不要修改 state
    1. 在 default 情况下返回旧的 state
    1. switch 语句并不是严格意义上的样板代码.
    1. reducer 合成,它是开发 Redux 应用最基础的模式。
    1. 每个 reducer 只负责管理全局 state 中它负责的一部分。每个 reducer 的 state 参数都不同,分别对应它管理的那部分 state 数据。

2.1 combineReducers

把一个由多个不同 reducer 函数作为 value 的 object,合并成一个最终的 reducer 函数,然后就可以对这个 reducer 调用 createStore.

换句话就是:

combineReducers() 所做的只是生成一个函数,这个函数来调用你的一系列 reducer, 每个 reducer 根据它们的 key 来筛选出 state 中的一部分数据并处理,然后这个生成的函数所所有 reducer 的结果合并成一个大的对象。

  import { combineReducers } from 'redux';
  const todoApp = combineReducers({
    visibilityFilter,
    todos
  });
  export default todoApp;
  // 完全等价
  export default function todoApp(state = {}, action) {
    return {
      visibilityFilter: visibilityFilter(state.visibilityFilter, action),
      todos: todos(state.todos, action)
    };
  }

3. Store

Store 就是把Action 和 Reducer联系到一起的对象。Store 有以下职责:

    1. 维持应用的 state;
    1. 提供 getState() 方法获取 state;
    1. 提供 dispatch(action) 方法更新 state;
    1. 通过 subscribe(listener) 注册监听器。

创建方式:

  import { createStore } from 'redux'
  import todoApp from './reducers'
  let store = createStore(todoApp)

3.1 createStore

接收2个参数:一个是当前action ,以及初始化是的state.state可选。

  createStore(reducer, [initialState])

4.数据流

严格的单向数据流是 Redux 架构的设计核心。

这意味着应用中所有的数据都遵循相同的生命周期,这样可以让应用变得更加可预测且容易理解。同时也鼓励做数据范式化,这样可以避免使用多个且独立的无法相互引用的重复数据。

Redux 应用中数据的生命周期遵循下面 4 个步骤:

    1. 调用 store.dispatch(action)。
    1. Redux store 调用传入的 reducer 函数。
    1. 根 reducer 应该把多个子 reducer 输出合并成一个单一的 state 树。(使用:combineReducers())
    1. Redux store 保存了根 reducer 返回的完整 state 树。

Redux使用场景

Redux 和 React 之间没有关系。Redux 支持 React、Angular、Ember、jQuery 甚至纯 JavaScript。

Redux 还是和 React 和 Deku 这类框架搭配起来用最好,因为这类框架允许你以 state 函数的形式来描述界面,Redux 通过 action 的形式来发起 state 变化。

参考文档

Redux 中文文档

isomorphic-fetch Ajax请求

koa服务器

babel编译

webpack打包

webpack英文原版

redux-thunk异步编程

React 入门实例教程

koa-react-isomorphic案例源码分析