React系列之 Flux架构模式

原文地址:https://gmiam.com/post/react-...

由于 React 只涉及 UI 层的处理,所以构建大型应用应该搭配一个框架模式才能使后期维护成本相对较小~

Flux 正是 FB 官方给出的应用架构,他推崇一种单向的数据流动模式,看下图感受下

da0d759007d119b9bb94140776651096.png

整个流程是

  • 用户与 View 层交互,触发 Action

  • Action 使用 Dispatcher 进行分发

  • Dispatcher 触发 Store 回调进行更新

  • Store 更新触发 View 层事件

  • View层 收到信号进行更新

相对传统 MV* 模式,Flux 一个最大的特色就是单向的数据流让事情变的可预见,看下面大型应用图感受下不同

MV*

alt

Flux

alt

其实概念说了一堆还是比较难理解,大家可以配合 flux-todomvc 官方示例来直观感受理解下

app.js 渲染的是 TodoApp.react.js 这个组件,组件内部从 TodoStore 获取数据传递给子组件,同时监听了 TodoStore 的数据变化,FB 管这种顶层 View 叫做 Controller-View

TodoApp.react.js

var TodoStore = require('../stores/TodoStore');

function getTodoState() {
  return {
    allTodos: TodoStore.getAll(),
    areAllComplete: TodoStore.areAllComplete()
  };
}

var TodoApp = React.createClass({

  getInitialState: function() {
   // 获取初始数据
    return getTodoState();
  },

  componentDidMount: function() {
    // 监听数据变化
    TodoStore.addChangeListener(this._onChange);
  },

  render: function() {
    return (
      <div>
        <Header />
        <MainSection
          allTodos={this.state.allTodos}
          areAllComplete={this.state.areAllComplete}
        />
        <Footer allTodos={this.state.allTodos} />
      </div>
    );
  },

  _onChange: function() {
    this.setState(getTodoState());
  }

});

TodoApp.react.js 又嵌套了几个子组件,这里我们关注下 Header.react.js 这个子组件感受一下整个流程就好了

Header.react.js 的子组件 TodoTextInput.react.js 监听 dom 输入框的各种事件,触发父组件传递给他的 Action 方法

Header.react.js

var TodoTextInput = require('./TodoTextInput.react');

var Header = React.createClass({
  render: function() {
    return (
      <header id="header">
        <h1>todos</h1>
        <TodoTextInput
          id="new-todo"
          placeholder="What needs to be done?"
          onSave={this._onSave}
        />
      </header>
    );
  },
  _onSave: function(text) {
    if (text.trim()){
      TodoActions.create(text);
    }
  }

});

TodoTextInput.react.js

var TodoTextInput = React.createClass({

  getInitialState: function() {
    return {
      value: this.props.value || ''
    };
  },

  render: function() /*object*/ {
    return (
      <input
        className={this.props.className}
        id={this.props.id}
        placeholder={this.props.placeholder}
        onBlur={this._save}
        onChange={this._onChange}
        onKeyDown={this._onKeyDown}
        value={this.state.value}
        autoFocus={true}
      />
    );
  },

  _save: function() {
    this.props.onSave(this.state.value);
    this.setState({
      value: ''
    });
  },

  _onChange: function(/*object*/ event) {
    this.setState({
      value: event.target.value
    });
  },

  _onKeyDown: function(event) {
    if (event.keyCode === ENTER_KEY_CODE) {
      this._save();
    }
  }

});

Action 执行 Dispatcher 进行行为分发,这里的 Dispatcher 是 FB 实现的一个事情分发系统

TodoActions.js

var TodoActions = {
  create: function(text) {
    AppDispatcher.dispatch({
      actionType: TodoConstants.TODO_CREATE,
      text: text
    });
  },
  ...
}

Dispatcher 的分发会触发 Store 中注册的回调,执行对应的行为更新数据,同时触发 Store Change 事件,那么 TodoApp.react.js 中监听的 Store Change 事件就会触发,重新设置组件的 state 数据,致使 View 重新 render

TodoStore.js

AppDispatcher.register(function(action) {
  var text;

  switch(action.actionType) {
    case TodoConstants.TODO_CREATE:
      text = action.text.trim();
      if (text !== '') {
        create(text);
        TodoStore.emitChange();
      }
      break;
    default:
      // no op
  }
});

这样就形成了 Flux 架构的单向闭环更新流,但是写起来还是有些繁琐和复杂性,下一节我们来看更简洁和优雅的方式 Redux ~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值