理解react开发中的redux、redux-thunk、Immutable

redux理解

  1. react的困扰

      项目开发中服务器响应、缓存数据、本地生成尚未持久化到服务器的数据、也包括UI状态,如激活的路由。被选中的标签、是否显示动效或者分页器等等。这些数据统称为state。

      由于js数据类型的特点,管理不断变化的 state 非常困难。当系统变得错综复杂的时候,想重现问题或者添加新功能就会变得举步维艰。

  2. redux的作用

    redux的作用就是用来管理混乱的state。
    redux三大原则:
         ①数据单一:整个应用state的被储存在一棵 object tree 中,并且这个 object tree 只存在于唯一一个store中。
         ②state 是只读的: 唯一改变 state 的方法就是触发action,action 是一个用于描述已发生事件的普通对象。
         ③使用纯函数来执行修改: 为了描述 action 如何改变 state tree ,你需要编写reducers。

  3. redux的常用API

    action: 它来描述“发生了什么”。它是 store 数据的唯一来源。一般来说你会通过 store.dispatch() 将 action 传到 store。在 Redux 中的 action 创建函数只是简单的返回一个 action。
        注:
       ① action对象中必须有type字段,用来指定将要执行的动作。
       ② action只是描述了有事情发生了这一事实,并没有描述应用如何更新 state。
    reducer: 它根据 action 更新 state。它指定了应用状态的变化如何响应 actions 并发送到 store 。reducer 是一个纯函数,接收旧的 state 和 action,返回新的 state。只要传入参数相同,返回计算得到的下一个 state 就一定相同。没有特殊情况、没有副作用,没有 API 请求、没有变量修改,单纯执行计算。
    store: 是把action和reducer联系到一起的桥梁。Redux 应用只有一个单一的 store。维持应用的 state;提供 getState() 方法获取 state; 提供 dispatch(action) 方法更新 state;通过 subscribe(listener) 注册监听器; 通过 subscribe(listener) 返回的函数注销监听器。
    connect: 通过react-redux提供的connect方法将我们需要的state中的数据和actions中的方法绑定到props上。

    原理解析
          首先connect之所以会成功,是因为Provider组件:

          在原应用组件上包裹一层,使原来整个应用成为Provider的子组件
          接收Redux的store作为props,通过context对象传递给子孙组件上的connect
    那connect做了些什么呢?
          它真正连接 Redux 和 React,它包在我们的容器组件的外一层,它接收上面 Provider 提供的 store 里面的 state 和 dispatch,传给一个构造函数,返回一个对象,以属性形式传给我们的容器组件。

    connect方法声明:

          connect([mapStateToProps], [mapDispatchToProps], [mergeProps],[options])
    参数介绍:
          mapStateToProps(state, ownProps) : stateProps
          这个函数允许我们将 store 中的数据作为 props 绑定到组件上。
          当 state 变化,或者 ownProps 变化的时候,mapStateToProps 都会被调用,计算出一个新的 stateProps,(在与 ownProps merge 后)更新给组件。

          mapDispatchToProps(dispatch, ownProps): dispatchProps
          它的功能是,将 action 作为 props 绑定到组件上,也会成为 MyComp 的 props。

redux-thunk理解

  1. react的困扰
          用户发出 Action,Reducer 函数算出新的 State,View 重新渲染。但是,一个关键问题没有解决:异步操作怎么办?Action 发出以后,Reducer 立即算出 State,这叫做同步;Action 发出以后,过一段时间再执行 Reducer,这就是异步。怎么才能 Reducer 在异步操作结束后自动执行呢?这就要用到新的工具:中间件(middleware)。

  2. redux-thunk的作用
          他允许你的action可以返回函数, 带有dispatch和getState两个参数, 在这个action函数里, 异步的dispatch action;

  3. redux-thunk的使用

    ① 安装:npm install redux-thunk --save-dev
    ② 导入thunk: import thunk from 'redux-thunk'
    ③ 导入中间件: import {createStore,applyMiddleware} from 'redux'
    ④ 创建store:let store = createStore(reducer函数,applyMiddleware(thunk))
    ⑤ 激活redux-thunk中间件,只需要在createStore中加入applyMiddleware(thunk)就可以

     1 /**
     2  * @author:水痕
     3  * @time:2017-03-28 08:48
     4  * @email:332904234@qq.com
     5  * @version:1.0
     6  * @fileName:index
     7  * @direction:
     8  * @title:
     9  */
    10 'use strict';
    11 import {createStore, applyMiddleware} from 'redux';
    12 import thunk from 'redux-thunk';
    13 
    14 function count(state = 0, action) {
    15     switch (action.type) {
    16         case 'ADD':
    17             return state + 1;
    18         case 'REDUCER':
    19             return state - 1;
    20         default:
    21             return state;
    22     }
    23 }
    24 const store = createStore(count,applyMiddleware(thunk));
    25 //action创建函数
    26 function add() {
    27     return {
    28         type: 'ADD',
    29     }
    30 }
    31 function reducer() {
    32     return {
    33         type: 'REDUCER'
    34     }
    35 }
    36 function addIfOdd() {
    37     return (dispatch, getState) => {
    38         const currentValue = getState();
    39         if (currentValue % 2 == 0) {
    40             return false;
    41         }
    42         dispatch(add())
    43     }
    44 }
    45 function addAsy(delay = 2000) {
    46     return (dispatch, getState) => {
    47         setTimeout(() => {
    48             dispatch(add())
    49         }, delay)
    50     }
    51 }
    52 
    53 //获取当前值
    54 let currentValue = store.getState();
    55 //创建一个监听
    56 store.subscribe(() => {
    57     const previosValue = currentValue;
    58     currentValue = store.getState();
    59     console.log('上一个值:', previosValue, '当前值:', currentValue)
    60 });
    61 
    62 //分发任务
    63 store.dispatch(add());
    64 store.dispatch(reducer());
    65 store.dispatch(addIfOdd());
    66 store.dispatch(addAsy());

Immutable理解

  1. react的困扰

    JavaScript 中的对象一般是可变的(Mutable),因为使用了引用赋值,新的对象简单的引用了原始对象,改变新的对象将影响到原始对象。如 foo={a: 1}; bar=foo; bar.a=2 你会发现此时 foo.a 也被改成了 2。虽然这样做可以节约内存,但当应用复杂后,这就造成了非常大的隐患,Mutable 带来的优点变得得不偿失。为了解决这个问题,一般的做法是使用 shallowCopy(浅拷贝)或 deepCopy(深拷贝)来避免被修改,但这样做造成了 CPU 和内存的浪费。

    Immutable 可以很好地解决这些问题。

  2. Immutable的作用

    Immutable数据就是一旦创建,就不能更改的数据。每当对Immutable对象进行修改的时候,就会返回一个新的Immutable对象,以此来保证数据的不可变。

  3. Immutable的常用API

    1.fromJS()
    作用:将一个js数据转换为Immutable类型的数据。

    用法:fromJS(value, converter)

    简介:value是要转变的数据,converter是要做的操作。第二个参数可不填,默认情况会将数组准换为List类型,将对象转换为Map类型,其余不做操作。

    代码实现:

    const obj = Immutable.fromJS({a:'123',b:'234'},function (key, value, path) {
            console.log(key, value, path)
            return isIndexed(value) ? value.toList() : value.toOrderedMap())
    })

    2.toJS()
    作用:将一个Immutable数据转换为JS类型的数据。

    用法:value.toJS()

    3.is()
    作用:对两个对象进行比较。

    用法:is(map1,map2)

    简介:和js中对象的比较不同,在js中比较两个对象比较的是地址,但是在Immutable中比较的是这个对象hashCode和valueOf,只要两个对象的hashCode相等,值就是相同的,避免了深度遍历,提高了性能。

    代码实现:

    1 import { Map, is } from 'immutable'
    2 const map1 = Map({ a: 1, b: 1, c: 1 })
    3 const map2 = Map({ a: 1, b: 1, c: 1 })
    4 map1 === map2   //false
    5 Object.is(map1, map2) // false
    6 is(map1, map2) // true

    4.List 和 Map
      创建
               List() 和 Map()

              作用:用来创建一个新的List/Map对象。

    数据读取
              get() 、 getIn()

    关于merge
              merge

              作用:浅合并,新数据与旧数据对比,旧数据中不存在的属性直接添加,旧数据中已存在的属性用新数据中的覆盖。

原文地址:https://www.cnblogs.com/dadouF4/p/10026728.html