[译] Flux 入门

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

原文链接The Flux Quick Start Guide

本文将概括性的介绍如何使用 Flux 架构开发 JavaScript 应用,用尽可能少的篇幅带你熟悉 Flux 的核心概念。你也可以结合 starter kit 一起学习。你最好先对 React 有基本的了解,并且有一些开发 React 组件的经验。如果不熟悉也没关系,可以先读一读这篇文章 The React Quick Start Guide (译注:中文版本 React 入门)。

概念

Flux 是用来构建用户端 Web 应用的架构,它包含三个核心概念:Views,StoresDispatcher,还有一些次级概念:Actions,Action Types,Action CreatorsWeb Utils

请耐心学习以下概念定义然后再看后面的教程。当你准备开始开发 Flux 应用之前,建议你再回过头来看一遍基本概念。

核心概念

  • Views 即 React 组件。它们负责渲染界面,捕获用户事件,从 Stores 获取数据。

  • Stores 用于管理数据。 一个 Store 管理一个区域的数据,当数据变化时它负责通知 Views。

  • Dispatcher 接收新数据然后传递给 Stores,Stores 更新数据并通知 Views。

次级概念

  • Actions 是传递给 Dispatcher 的对象,包含新数据和 Action Type。

  • Action Types 指定了可以创建哪些 Actions,Stores 只会更新特定 Action Type 的 Actions 触发的数据。

  • Action Creators 是 Actions 的创建者,并将其传递给 Dispatcher 或 Web Utils。

  • Web Utils 是用于与外部 API's 通信的对象。例如 Actions Creator 可能需要从服务器请求数据。

是不是一次给的信息量太多啦?强烈建议你们结合 starter kit 边看文章边敲代码,可以达到更好的学习效果

提示:这里省略了 constants 和 Web Utils,是为了更快速简单地理解 Flux。更深入阅读 官方示例 能很好地补充这些知识。

Views

部署好 starter kit 后,你会看到在 @H_502_83@src 目录下有个 @H_502_83@app.js 文件

var React = require('react');
var Comments = require('./views/comments');
var CommentForm = require('./views/comment-form');

var App = React.createClass({
  
  render: function() {
    return (
      <div>
        <Comments />
        <CommentForm />
      </div>  
    );
  }
});

React.render(<App />,document.getElementById('app'));

上面代码把 Views 渲染到 DOM 中。先忽略 @H_502_83@Comments,看一下 @H_502_83@CommentFrom 的实现。

var React = require('react');

var CommentActionCreators = require('../actions/comment-action-creators');

var CommentForm = React.creatClass({
  
  onSubmit: function(e) {
    var textNode = this.refs.text.getDOMNode();
    var text = textNode.value;

    textNode.value = '';

    CommentActionCreators.createComment({
      text: text
    });
  },render: function() {
    return (
      <div className='comment-form'>
        <textarea ref='text' />
        <button onClick={this.onSubmit}>Submit</button>
      </div>
    );
  }
});

module.exports = CommentForm;

@H_502_83@CommentForm 依赖的 @H_502_83@CommentActionCreators 是一个 Action Creator (正如它的名字一样)。

当表单提交时 @H_502_83@createComment 函数传递了 @H_502_83@comment 对象,它的值是根据 textarea 的值构造出来的。让我们开发这个 Action Creator 来接收 comment。

Actions

在 @H_502_83@actions 目录里有如下的 @H_502_83@comment-action-creators.js 文件

var AppDispatcher = require('../dispatcher/app-dispatcher');

module.exports = {
  
  createComment: function(comment) {
    var action= {
      actionType: "CREATE_COMMENT",comment: comment
    };

    AppDispatcher.dispatch(action);
  }
};

@H_502_83@createComment 函数构造了一个 Action,包含 Action Type 和 comment 数据,并将这个 Action 传递给 Dispatcher 的 @H_502_83@dispatch 函数

接下来编写 Dispatcher 用于接收 Actions。

提示:也可以把这些逻辑写在 View 里面 - 直接跟 Dispatcher 通信,但最佳实践是用 Action Creator。它能降低代码的耦合度并给 Dispatcher 提供一个单独的接口。

Dispatcher

在 @H_502_83@dispatcher 目录下有一个 @H_502_83@app-dispatcher.js 文件

var Dispatcher = require('flux').Dispatcher;

module.exports = new Dispatcher();

Flux 库的 Dispatcher 提供了一个 @H_502_83@dispatch 函数,将接收到的 Actions 传递给所有注册的回调函数,回调函数由 Stores 提供。

提示:这里没有 Dispatcher 的具体实现,源码在这里


Stores

在 @H_502_83@stores 目录下有一个 @H_502_83@comment-store.js 文件

var AppDispatcher = require('../dispatcher/app-dispatcher');

var EventEmitter = require('events').EventEmitter;
var assign = require('object-assign');


var comments = [];

var CommentStore = assign({},EventEmitter.prototype,{
  
  emitChange: function() {
    this.emit('change');
  },addChangeListener: function(callback) {
    this.on('change',callback);
  },removeChangeListener: function(callback) {
    this.removeListener('change',getAll: function() {
    return comments;
  }
});

AppDispatcher.register(function(action) {
  switch(action.actionType) {

    case "CREAT_COMMENT":
      comments.push(action.comment);
      CommentStore.emitChange();
      break;

    default:
  }
});

module.exports = CommentStore;

这段代码分为两部分:创建 Store 和 注册 Store。

Store 由 @H_502_83@EventEmitter.prototype 和自定义对象整合而成。@H_502_83@EventEmitter.prototype 给 Store 赋予了订阅和触发事件的能力。

自定义对象定义了订阅和取消订阅事件的函数,同时定义了 @H_502_83@getAll 函数返回 @H_502_83@comments 数据。

然后,通过 Dispatcher 注册了一个回调函数。当 Dispatcher 调用 @H_502_83@dispatch 时传递 Actions 参数给每个注册过的回调函数

现在我们需要一个 View 来展示 Store 的数据,并订阅数据的变化。

在 @H_502_83@views 目录里有个 @H_502_83@comments.js 文件。把它修改成如下所示:

var React = require('react');

var CommentStore = require('../stores/comment-store');

function getStateFromStore() {
  return {
    comments: CommentStore.getAll()
  }
}

var Comments = React.createClass({
  
  onChange: function() {
    this.setState(getStateFromStore());
  },getInitialState: function() {
    return getStateFromStore();
  },componentDidMount: function() {
    CommentStore.addChangeListener(this.onChange);
  },componentWillUnmount: function() {
    CommentStore.removeChangeListener(this.onChange);
  },render: function() {
    var comments = this.state.comments.map(function(comment,index) {
      return (
        <div className='comment' key={'comment-' + index}>
          {comment.text}
        </div>
      );
    });

    return (
      <div className='comments'>
        {comments}
      </div>
    )
  }
});

module.exports = Comments;

@H_502_83@getStateFromStores 函数从 Store 获取 comment 数据,并在 @H_502_83@getInitialState 中设置为初始值。

在 @H_502_83@componentDidMount 中,@H_502_83@onChange 函数作为 @H_502_83@addChangeListener 的回调函数,当 Store 触发 @H_502_83@change 事件时 @H_502_83@onChange 函数将被调用,即当 Store 数据变化时,它用于更新组件的 state 状态。

最后 @H_502_83@componentWillUnmount 将 @H_502_83@onChange 事件监听从 Store 移除。

结语

现在这个 Flux 应用可以运行起来了,同时我们也学习了 Flux 架构的核心概念:Views,Stores 和 Dispatcher。

  • 当提交 comment 时,View 调用了 Action Creator

  • Action Creator 创建一个 Action 并传给 Dispatcher

  • Dispatcher 将 Action 发送给 Store 中注册的回调函数

  • Store 更新 comment 数据,并触发一个 change 事件

  • View 更新 state 并重新渲染界面

这就是 Flux 的本质,Dispatcher 发送数据给所有 Stores,后者通知 Views 进行更新。

要想更深入理解 Flux 架构,我建议阅读 官方文档,或者看看这个 视频教程,还有 官方示例

如果本文有什么错误之处,欢迎在 twitter 上联系我,或者给我提 pull request。欢迎大家给我提建议改善这边文章

猜你在找的React相关文章