学 react 势必要学习 redux , 初学 redux 的时候, 觉得 redux 很鸡肋, 根据我的经验来看, 我认为 redux 的设计非常的反设计原则, 为什么这么说呢. 我们先来看看 redux 做了什么事情.
redux 的两种身份
1, 发布 / 订阅 模型
首先 redux 可以认为是 发布 / 订阅 模型的一种实现, 组件通过 action 发布事件, 经过 reducer 处理后, 将改变后的数据通知到订阅 stroe 的组件, 然后触发监听 store 的组件的变动.
2, 全局 state 存储
redux 通过 store 存储几乎所有的数据信息, 将数据平铺在一个大 JSON 中, 便于各处获取使用.
redux 违反的原则
1, 破坏了内聚性
一般来说, 我们认为组件是包含 数据 + 逻辑 + 视图 的集合, 但是用了 redux 后, 我们将数据全部存放到 store 中, 将逻辑置于 redurce 中, 而组件内部往往只剩下了 视图 这么一个功能, 导致组件的交互必须要与外部 store 发生关联, 并且这些操作都由 reducer 完成, 这些内容外部是可见的. 这违反了内聚性.
2, 违反了迪米特法则
迪米特法则也即最小知识原则, 由于所有的数据铺开在一起, 假设现在页面中有 A,B,C 三个组件, 现在 A 组件的一个事件 t 会引发 B,C 的变更, 通常来说, 好的做法是 A 将 t 事件通知给一个公共的消息处理中心, 而 B,C 订阅了 t 事件, 由消息中心将事件 t 广播给 B,C , 然后 B,C 执行相应的操作, 在这个过程中, A 对 B 和 C 是无感知的, 这样即是高内聚的做法. 但是在 redux 中, 当事件出现的时候, reducer 需要根据事件, 依次地修改 B,C 所连接的 store 的部分, 这就需要 t 事件要能了解 B 和 C 的存在, 如果这个时候添加一个新的组件 D 一起来联动, 则需要修改 reducer 中对 t 事件的处理方法. 而上一种方法则只需要在 D 中自行添加处理方法就好.
为什么还要 redux?
既然 redux 缺点那么多, 那么为什么还需要 redux 呢?! 因为
react 是单向数据流的. 外部组件难以获取内部组件的数据.
这点很重要, 根据 react 的哲学 Thinking in React , 通常来说 props 用于将外部的数据透传到组件内部, 而 state 用于处理组件内部的状态. 这样设计通常来看是没有问题的, 但是一旦遇到需要将内部组件的数据传递到外部的时候就出现问题了. 一般我们通过传入一个回调函数来将内部的数据透传到外部, 但是这个回调函数是需要组件内部来触发的, 但是如果组件内部不主动触发, 我们基本上是没有办法获取组件内部数据的.
react 和 数据内聚
在 Java 中, 我们设计好一个高内聚的类, 它自身能完成一系列复杂的操作, 当我们需要获取操作结果或内容的时候, 我们只需要在类添加一个方法, 然后使用方主动调用这个方法就好了. 但是由于 react 单向数据的设计, 我们没法让外部主动触发获取内部组件数据的操作. 如果在外部组件中声明全部的数据, 又会导致所有的内部组件和外部组件紧耦合, redux 提供了一个折中的方法, 将数据从业务逻辑中抽象出来, 各个组件订阅 store 中自己关心的部分, 通过这样的方式, 减少对外部组件的依赖, 又利于数据在全局间互通, 让外部组件可以通过 redux 轻松获取内部组件的数据.
思考: 设计和模型
架构设计这个事情, 很多时候根据出发角度的不同, 会得到完全不同的结果, 仔细思考 redux 的设计是有其取舍之处的, 之所以一开始会得到十分负面的感受, 是因为一开始的时候, 我们站在肉眼所看的模块出发, 认为一个页面模块就应该是一个高内聚的组件, 但是忽略了 react 的限制, 而 redux 更能看到 react 的限制, 在其中找寻合适的平衡.
来源: http://www.css88.com/qa/react/14446.html