Skip to content

Latest commit

 

History

History
68 lines (61 loc) · 2.36 KB

24.one-way-data-flow.md

File metadata and controls

68 lines (61 loc) · 2.36 KB

单向数据流

单向数据流只关注于在store中维护的唯一的state,消除了不必要的多种states带来的复杂度. 这个store应该具有能被我们订阅(subscribe)store中变化的能力,实现如下:

var Store = {
  _handlers: [],
  _flag: '',
  onChange: function (handler) {
    this._handlers.push(handler);
  },
  set: function (value) {
    this._flag = value;
    this._handlers.forEach(handler => handler())
  },
  get: function () {
    return this._flag;
  }
};

然后我们会在我们的App组件上加上订阅我们的store的钩子, 当每次store发生改变的时候, 我们的组件就会被重新的渲染.

class App extends React.Component {
  constructor(props) {
    super(props);
    Store.onChange(this.forceUpdate.bind(this));
  }

  render() {
    return (
      <div>
        <Switcher
          value={ Store.get() }
          onChange={ Store.set.bind(Store) }/>
      </div>
    );
  }
}

请注意我们使用了forceUpdate这个函数,但是事实上我们并不推荐使用这个函数.

一般情况下我们会使用高阶组件去帮我们处理重新渲染的事情,我们在这里使用forceUpdate函数只是想尽可能的保持我们这个例子简单.

因为我们使用了store, Swticher这个组件就变得超级简单了. 我们不需要再在Switcher组件内部再去维护一份State了:

class Switcher extends React.Component {
  constructor(props) {
    super(props);
    this._onButtonClick = e => {
      this.props.onChange(!this.props.value);
    }
  }

  render() {
    return (
      <button onClick={ this._onButtonClick }>
        { this.props.value ? 'lights on' : 'lights off' }
      </button>
    );
  }
}

使用单向数据流的好处是我们的组件在这种情况下变得非常声明式, 成为了所谓的纯UI组件, 只是我们Store里面数据的表达. React在诞生之初就是为了解决视图层(View层)的问题, 其核心思想也是从视图出发去解决问题. 我们用声明式的方式去构建我们的应用, 让我们的组件变得尽可能的木偶化,只关心我们的数据,将我们的复杂的数据逻辑交由我们的store去处理. 这也是我们去构建React应用的时候的一种比较好的思路.

参考资料: