2015-04-26 3 views
1

В настоящее время у меня очень простое приложение React, которое использует состояние для определения пары представлений. Нажатие на элемент submit вызывает простой вызов конечной точке, передающей логин или учетные данные. Я мог бы продолжить эту дорогу, чтобы использовать React, и JSON вернулся с сервера, чтобы определить мои взгляды, но я знаю, что это не подходит для обработки данных.Понимание того, как реализовать Flux-архитектуру с использованием Flummox

Мой вопрос: отсюда, как я могу использовать шаблон потока с использованием Flummox? Я запускаю действие с помощью полезной нагрузки и вызываю вызов API в действии или в магазине? Я пытаюсь понять, как правильно сделать этот переход из действия в моем пользовательском интерфейсе, моем вызове API, чтобы получить ответ и пользовательский интерфейс, реагирующий на изменение в магазине.

Ниже приведен код для моего компонента Auth. Я хотел бы посмотреть пример использования Flummox в такой простой ситуации, чтобы я мог понять, что нужно для масштабирования и добавления функций.

Auth.jsx

'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; 

ответ

12

Перед погружением в Flux, я хотел бы предложить, чтобы очистить существующий React код у вас есть.

В начале я попытался как можно больше уменьшить собственное состояние компонента. Например, вместо того, чтобы иметь отдельное состояние для login и register, вы можете иметь одно состояние screen в качестве состояния, которое принимает строковое значение фактического экрана/представления, которое вы выполняете (вход/регистрация).

Кроме того, каждый из renderLogin() и renderRegister() лучше как компоненты самостоятельно. Поэтому ваш компонент Auth окажется в виде контроллера.

Обработка формы выглядит слишком много в одно и то же время: вы определили отдельный обработчик для каждого отдельного поля, но достаточно одного handleChange() (вы можете установить name="<state-field-name>" в своих элементах ввода, чтобы ссылаться на поле состояния, на которое вы ссылаетесь).


Afer, что вы можете начать строить структуру потока с помощью смущать и перемещение вашего состояния приложения (а не локальное состояние компонента) в магазины.

Я предполагаю, что у вас есть read the docs, но в резюме Flummox предлагает Store и Action помощники, чтобы моделировать данные вашего приложения (источник правды) и действия пользовательского интерфейса.

Модуль действия может выглядеть следующим образом:

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 будет источником истины, то есть обрабатывает фактическое состояние приложения. Это регистрируется с помощью действий, поэтому он знает, как обновлять себя всякий раз, когда изменения происходят от действий.

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 объект, который затем можно ссылаться из любого места в вашем приложении.

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 вашего приложения, и вам также необходимо указать, к каким хранилищам он хочет подключиться.

import Flux from './Flux'; 
let flux = new Flux(); 

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

Состояние передается как реквизит, и вы можете ссылаться на значения непосредственно, как обычно, с помощью реквизита.

В то же время, это позволяет получить доступ к flux опоры в нижележащем виде, который дает нам доступ к действиям, и, следовательно, способны вызвать их, когда взаимодействие с пользователем происходит:

// You can fire actions from anywhere in your component 
this.props.flux.getActions('auth').gotoScreen('register') 

С этим заканчивается (или начинается) цикл потока.

+0

Это именно тот тип объяснений, который я искал. благодарю вас за то, что нашли время, чтобы изложить это и подробно объяснить процесс, а также предложить, как реорганизовать многословие этого простого компонента. –

Смежные вопросы