首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >了解如何使用Flummox实现Flux体系结构

了解如何使用Flummox实现Flux体系结构
EN

Stack Overflow用户
提问于 2015-04-26 20:43:48
回答 1查看 1.1K关注 0票数 1

我目前有一个非常简单的React应用程序,它使用状态来确定几个视图。单击submit元素会简单地调用传递登录或注册凭据的端点。我可以沿着这条路继续使用React和从服务器返回的JSON来确定我的视图,但我知道这种处理数据的方式不合适。

我的问题是,从这里开始,如何使用Flummox实现Flux模式?我是用有效负载触发一个操作,并在操作或存储中调用API吗?我正试图理解从UI中的操作到API调用,再到响应商店中的更改的响应和UI往返的正确方法。

下面是我的Auth组件的代码。我希望看到一个关于如何在这样简单的情况下使用Flummox的例子,这样我就可以理解扩展和添加特性所需的内容。

Auth.jsx

代码语言:javascript
复制
'use strict';

var React  = require('react');
var request = require('request');

var Auth = React.createClass({

  getInitialState: function() {
    return {
      name: '',
      email: '',
      pass: '',
      passConfirm: '',
      login: true,
      register: false
    };
  },

  handleLogin: function(){
    this.setState({
      login: true,
      register: false
    });
  },

  handleRegister: function(){
    this.setState({
      register: true,
      login: false
    });
  },

  handleName: function(event){
    this.setState({
      name: event.target.value
    });
  },

  handleEmail: function(event){
    this.setState({
      email: event.target.value
    });
  },

  handlePass: function(event){
    this.setState({
      pass: event.target.value
    });
  },

  handlePassConfirm: function(event){
    this.setState({
      passConfirm: event.target.value
    });
  },

  handleSubmit: function(){

    var register = {
      name: this.state.name,
      email: this.state.email,
      password: this.state.pass,
      confirmPassword: this.state.passConfirm
    };

    var endpoint = 'http://localhost:3000';

    request({
       uri: endpoint + '/register',
       method: 'POST',
       json: register
   }, function(error, response, body){
       if (error) {
         console.log(error);
       } else {
         console.log(response);
       }
   });
  },

  renderLogin: function () {
    return (
      <form className="login">
        <div className="input-container">
          <input type='text' value={this.state.email} onChange={this.handleEmail} placeholder="email" />
          <input type='password' value={this.state.password} onChange={this.handlePass} placeholder="password" />
        </div>

        <div className="auth-submit" onClick={this.handleSubmit}>Login</div>
      </form>
    );
  },

  renderRegister: function(){

    return (
      <form className="register">
        <div className="input-container">
          <input type='text' value={this.state.name} onChange={this.handleName} placeholder="name" />
          <input type='email' value={this.state.email} onChange={this.handleEmail} placeholder="email" />
          <input type='password' value={this.state.pass} onChange={this.handlePass} placeholder="password" />
          <input type='password' value={this.state.passConfirm} onChange={this.handlePassConfirm} placeholder="confirm password" />
        </div>

        <div className="auth-submit" onClick={this.handleSubmit}>Register</div>
      </form>
    );
  },

  render: function(){

    var auth = null;
    if (this.state.login) {
      auth = this.renderLogin();
    } else if (this.state.register) {
      auth = this.renderRegister();
    }

    return (
      <div className="auth-container">
        <div className="auth-logo">Flow</div>
        {auth}
        <div className="auth-select">
          <div className="auth-label-container">
            <div className="auth-label" onClick={this.handleLogin}>Login</div>
          </div>
          <div className="auth-label-container">
            <div className="auth-label" onClick={this.handleRegister}>Register</div>
          </div>
        </div>
      </div>
    );
  },
});

module.exports = Auth;
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-04-27 08:50:11

在深入研究Flux之前,我建议清理现有的React代码。

首先,我会尽量减少组件本身的状态。例如,不需要为loginregister设置单独的状态,您可以有一个screen作为状态,它接受正在呈现的实际屏幕/视图的字符串值(登录/注册)。

而且,每个renderLogin()renderRegister()作为它们自己的组件都更好。因此,您的Auth组件最终将是一个控制器视图。

表单处理同时看起来过于冗长:您已经为每个字段定义了一个单独的处理程序,但是一个handleChange()就足够了(您可以在输入元素中设置name="<state-field-name>"来引用所引用的状态字段)。

在您可以开始使用Flummox构建流量模式并将应用程序状态(而不是本地组件状态)移动到存储区之后。

我假设您有read the docs,但总的来说,Flummox提供了StoreAction帮助工具来建模应用程序的数据(真实来源)和UI操作。

actions模块可以如下所示:

代码语言:javascript
复制
import { Actions } from 'flummox';


export default class AuthActions extends Actions {

  gotoScreen(screenName) {
    return screenName;
  }

  register(requestBody) {
    // Here you deal with your authentication API,
    // make async requests and return a promise.
    // This part is specific to your backend.
    return AuthAPI.register(requestBody)
                  .then(
                    (value) => Promise.resolve(value),
                    (reason) => Promise.reject(reason)
                  );
  }

}

AuthStore将是真相的来源,即处理实际的应用程序状态。这将使用操作注册,因此它知道如何在操作发出更改时更新自己。

代码语言:javascript
复制
import { Store } from 'flummox';


export default class AuthStore extends Store {

  constructor(flux) {
    super();

    let authActions = flux.getActions('auth');

    // Here you register the functions which will take care
    // of handling the actions and update the store's state.
    // These can be sync or async.
    this.register(authActions.gotoScreen, this.handleGotoScreen);
    this.registerAsync(authActions.register, this.handleRegisterBegin,
                                             this.handleRegisterSuccess,
                                             this.handleRegisterError);

    // This is the initial state of your flux store
    this.state = {
      screen: 'login',
      // ... any extra state your app might need
    };
  }


  /* Screen handling */

  handleGotoScreen(screenName) {
    this.setState({screen: screenName});
  }

  /* Register */

  handleRegisterBegin(requestBody) {
    this.setState({
      // change state based on action
    });
  }

  handleRegisterSuccess() {
    this.setState({
      // change state based on action
    });
  }

  handleRegisterError(errors) {
    this.setState({
      // change state based on action
    });
  }

}

这些需要封装在Flux对象中,然后可以从应用程序中的任何地方引用。

代码语言:javascript
复制
import { Flummox } from 'flummox';

import AuthActions from './AuthActions';
import AuthStore from './AuthStore';


export default class Flux extends Flummox {

  constructor() {
    super();

    this.createActions('auth', AuthActions);
    this.createStore('auth', AuthStore, this);
  }

}

但是你的观点怎么知道商店的状态呢?用视图粘合商店的preferred way是通过使用FluxComponent来实现的,当使用FluxComponent时,通过道具接收存储的状态。

FluxComponent接收应用程序的Flux对象的一个实例,您还需要指定它想要连接到的存储区。

代码语言:javascript
复制
import Flux from './Flux';
let flux = new Flux();

<FluxComponent flux={flux} connectToStores={['auth']}>
  <Auth />
</FluxComponent>

状态作为道具传递,您可以像通常使用道具那样直接引用这些值。

同时,这允许访问底层视图中的flux支柱,这使我们能够访问操作,因此能够在发生用户交互时触发它们:

代码语言:javascript
复制
// You can fire actions from anywhere in your component
this.props.flux.getActions('auth').gotoScreen('register')

这样就完成(或开始)了通量循环。

票数 12
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29883283

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档