• 【转】关于Redux


    一、Redux

    前端框架->React->插件

      在MVC的世界里,React相当于View的部分,只涉及到页面的渲染,一旦需要涉及到应用的数据管理,还是需要交给Model和Controller,但是Redux并不是一个MVC框架,它用一种新的思路来管理数据。

    MVC

      MVC是业界广泛接受的一种前端应用框架类型,这种框架把应用分为三个部分:

      Model(模型)负责管理数据,大部分业务逻辑应该放在Model中

      View(视图)负责渲染用户页面,应该避免在View中涉及业务逻辑

      Controller(控制器)负责接受用户输入,根据用户输入调用相应的Model部分逻辑,把产生的数据结果交给View部分,让View渲染出必要的输出

      MVC框架提出的数据流很理想,用户请求先到达Controller,由Controller调用Model获得数据,然后把数据交给View。但是,在实际框架实现中,总是允许View和Model直接通信

      然而,在MVC中让View和Model直接对话就是灾难

    Flux

    【优势】

      在Flux中,Store只有get方法,没有set方法,根本不可能直接去修改其内部状态,View只能通过get方法获取Store的状态,无法直接去修改状态,如果View想要修改Store的状态,只能派发一个action对象给Dispatcher

    【不足】

      1、Store之间依赖关系

      在Flux的体系中,如果两个Store之间有逻辑依赖关系,就必须用上Dispatcher的waitFor函数

      2、难以进行服务器端渲染

      3、Store混杂了逻辑和状态

    Redux

      Redux的含义是Reducer+Flux。Reducer是一个计算机科学中的通用概念。以Javascript为例,数组类型有reduce函数,接受的参数是一个reducer,reducer做的事情就是把数组所有元素依次做规约,对每个元素都调用一次参数reducer,通过reducer函数完成规约所有元素的功能

      Flux的基本原则是单向数据流,Redux在此基础上强调三个基本原则:

      1、唯一数据源

      2、保持状态只读

      3、数据改变只通过纯函数完成

    Redux

      Redux的含义是Reducer+Flux。Reducer是一个计算机科学中的通用概念。以Javascript为例,数组类型有reduce函数,接受的参数是一个reducer,reducer做的事情就是把数组所有元素依次做规约,对每个元素都调用一次参数reducer,通过reducer函数完成规约所有元素的功能

      Flux的基本原则是单向数据流,Redux在此基础上强调三个基本原则:

      1、唯一数据源

      2、保持状态只读

      3、数据改变只通过纯函数完成

    容器和展示

      一个React组件基本上要完成以下两个功能:

      1、读取Store的状态,用于初始化组件的状态,同时还要监听Store的状态改变;当Store状态发生变化时,需要更新组件状态,从而驱动组件重新渲染;当需要更新Store状态时,就要派发action对象

      2、根据当前props和state,渲染出用户界面

      让一个组件只专注做一件事。于是,按照这两个功能拆分成两个组件。这两个组件是父子组件的关系。业界对于这样的拆分有多种叫法,承担第一个任务的组件,也就是负责和redux打交道的组件,处于外层,被称为容器组件;只专业负责渲染界面的组件,处于内层,叫做展示组件

      展示组件,又称为傻瓜组件,就是一个纯函数,根据props产生结果。实际上,让展示组件无状态,只根据props来渲染结果,是拆分的主要目的之一。状态全部交给容器组件去处理

    或者,直接使用解构赋值的方法 

    React-redux

      react-redux遵循将组件分成展示组件和容器组件的规范。react-redux提供了两个功能:

      1、Provider组件,可以让容器组件默认可以取得state,而不用当容器组件层级很深时,一级级将state传下去

         2、connect方法,用于从展示组件生成容器组件。connect的意思就是将这两种组件连接起来

    模块化应用

      从架构出发,开始一个新应用时,有几件事情是一定要考虑清楚的:

      1、代码文件的组织结构

      2、确定模块的边界

      3、Store的状态树设计

    【代码文件的组织结构】

      Redux应用适合于按功能组织,也就是把完成同一应用功能的代码放在一个目录下,一个应用功能包含多个角色的代码。在Redux中,不同的角色就是reducer、actions和视图。而应用功能对应的就是用户界面上的交互模块

      以Todo应用为例,这个应用的两个基本功能就是TodoList和Filter,所以代码可以这样组织:

    【模块接口】

      不同功能模块之间的依赖关系应该简单而清晰,也就是所谓的保持模块之间低耦合性;一个模块应该把自己的功能封装得很好,让外界不要太依赖于自己内部的结构,这样不会因为内部的变化而影响外部模块的功能,这就是所谓的高内聚性

    【状态树的设计】

      状态树的设计需要遵循如下几个原则:

      1、一个模块控制一个状态节点

      2、避免冗余数据

      3、树形结构扁平  (避免依赖)

      对于Todo应用的状态树设计如下

    reselect

      reselect库的原理是只要相关状态没有改变,那就直接使用上一次的缓存结果。reselect用来创造选择器,接收一个state作为参数的函数,返回的数据是某个mapStateToProps需要的结果

      首先,安装reselect库

        npm install --save reselect

      reselect提供了创造选择器的createSelector函数,这是一个高阶函数,也就是接受函数为参数来产生一个新函数的函数

      createSelector 接收一个 input-selectors 数组和一个转换函数作为参数。如果 state tree 的改变会引起 input-selector 值变化,那么 selector 会调用转换函数,传入 input-selectors 作为参数,并返回结果。如果 input-selectors 的值和前一次的一样,它将会直接返回前一次计算的数据,而不会再调用一次转换函数。

    常见错误

      在使用redux的过程中,会出现如下的常见错误

    【错误:reducers不能触发actions】

          Uncaught Error: Reducers may not dispatch actions.

    一般来说,出现"Reducedrs may not dispatch actions"的错误,是因为reducer中出现路由跳转语句,而跳转到的语句正好发送了dispatch。从而,reducer不再是纯函数

    【redux中的state发生变化,但页面没有重新渲染】

      一般地,是因为展开运算符使用不当所至

      对于对象的展开运算符,需要把...state放到第一个条目位置,因为后面的条目会覆盖展开的部分

          return {...item,completed:!item.completed}

    【reducer中不能使用undefined】

      1、reducer中state不能返回undefined,可以用null代替

  • 相关阅读:
    Centos 端口开放 Firewall
    windows 命令
    macOS 提示已损坏无法打开解决办法
    Linux screen
    pixhawk入门知识
    [转]错误记录
    华为上机试题:最高分是多少
    [转]opencv学习资料
    像素点的Hessian矩阵
    排序算法
  • 原文地址:https://www.cnblogs.com/lemonMie/p/9335618.html
Copyright © 2020-2023  润新知