redux原理分析

前端之家收集整理的这篇文章主要介绍了redux原理分析前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

redux介绍

redux是一个针对JavaScript应用的可预测的状态管理器。

redux中的设计模式

装饰者模式

定义:装饰者模式用于给对象动态地增加职责。

我们来看看redux最早期(v0.2.0)的github代码

  1. //Counter.js
  2. import React from 'react';
  3. import { performs,observes } from 'redux';
  4.  
  5. @performs('increment','decrement','double')
  6. @observes('CounterStore')
  7. export default class Counter {
  8. render() {
  9. const { increment,decrement } = this.props;
  10. return (
  11. <p>
  12. Clicked: {this.props.counter} times
  13. {' '}
  14. <button onClick={() => increment()}>+</button>
  15. {' '}
  16. <button onClick={() => decrement()}>-</button>
  17. {' '}
  18. <button onClick={() => double()}>double</button>
  19. </p>
  20. );
  21. }
  22. }

经过observes的包装后,react组件可以访问Redux store里的couter数据;经过performs的包装后,react组件可以发起increment、decrement和double这3个Action。

我们来看看performs是怎么包装react组件的:

  1. //performs.js
  2. import React,{ Component,PropTypes } from 'react';
  3. import pick from 'lodash/object/pick';
  4. import identity from 'lodash/utility/identity';
  5.  
  6. const contextTypes = {
  7. getActions: PropTypes.func.isrequired
  8. };
  9.  
  10. export default function performs(...actionKeys) {
  11. let mapActions = identity;
  12.  
  13. return function (DecoratedComponent) {
  14. const wrappedDisplayName = DecoratedComponent.name;
  15.  
  16. return class extends Component {
  17. static displayName = `ReduxPerforms(${wrappedDisplayName})`;
  18. static contextTypes = contextTypes;
  19.  
  20. constructor(props,context) {
  21. super(props,context);
  22. this.updateActions(props);
  23. }
  24. updateActions(props) {
  25. this.actions = mapActions(
  26. pick(this.context.getActions(),actionKeys),props
  27. );
  28. }
  29.  
  30. render() {
  31. return (
  32. <DecoratedComponent {...this.actions} />
  33. );
  34. }
  35. };
  36. };
  37. }

很简单对不对,performs实质上是一个高阶函数,接收一个react组件类型的参数DecoratedComponent,然后返回一个高阶组件,该组件包装了传递进来的react组件,并向该组件传递了action相关的props.

通过可以看上面的图可以看出,Counter组件被Observes包装后,又被performs包装,形成了一条包装链。

redux提供的API中,有一个重要的方法connect,用于连接 React 组件与 Redux store。连接操作不会改变原来的组件类,而是返回一个新的已与 Redux store 连接的组件类。典型的装饰者模式有木有?

观察者模式

定义:观察者模式又叫发布-订阅模式,它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖它的对象都将得到通知

  1. @observes('CounterStore')

counter.js的这行代码表示它对Redux的CounterStore数据进行订阅。我们来看看objserves的实现:

  1. //observes.js
  2. import React,PropTypes } from 'react';
  3. import pick from 'lodash/object/pick';
  4.  
  5. const contextTypes = {
  6. observeStores: PropTypes.func.isrequired
  7. };
  8.  
  9. export default function connect(...storeKeys) {
  10.  
  11. return function (DecoratedComponent) {
  12.  
  13. const wrappedDisplayName = DecoratedComponent.name;
  14.  
  15. return class extends Component {
  16. static displayName = `ReduxObserves(${wrappedDisplayName})`;
  17. static contextTypes = contextTypes;
  18.  
  19. constructor(props,context);
  20. this.handleChange = this.handleChange.bind(this);
  21. this.unobserve = this.context.observeStores(storeKeys,this.handleChange); //订阅store数据
  22. }
  23. handleChange(stateFromStores) {
  24. this.currentStateFromStores = pick(stateFromStores,storeKeys);
  25. this.updateState(stateFromStores);
  26. }
  27. updateState(stateFromStores,props) {
  28. stateFromStores = stateFromStores[storeKeys[0]];
  29. const state = stateFromStores;
  30. this.setState(state);//通过setState进行组件更新
  31. }
  32.  
  33. componentWillUnmount() {
  34. this.unobserve();//退订
  35. }
  36.  
  37. render() {
  38. return (
  39. <DecoratedComponent {...this.props}
  40. {...this.state} />
  41. );
  42. }
  43. };
  44. };
  45. }

当数据变化时,通过调用setState方法,进而对Counter组件进行UI更新。

猜你在找的React相关文章