组件之间的通信

时间:2014-10-25 21:26:08

标签: reactjs flux reactjs-flux

在这里,我的情况,我是一个非常新的反应/流量,并开始玩它。我的玩具项目是一个简单的图书馆应用。我目前的状况如下:

  • 我有一个名为Login的组件。该组件仅负责存储当前"登录"用户能够处理库中后面的Borrow / Return按钮。因此,用户输入其名称,此名称将被保存到会话存储中。
  • 我的另一个组件名为Library,它包含我的应用程序的主要逻辑。

如果我更改当前用户,我很难找到如何重新渲染我的库组件。从我的第一个项目开始,我就不想使用正确的身份验证,或者创建路由器。所以我只是创建了一个Login表单,每当用户输入他的名字并登录时,我就会将库应用程序渲染到DOM上。

Login = React.createClass({

  _handleSubmit: function () {

    var inp = this.refs.login.getDOMNode();

    sessionStorage.setItem("username", inp.value);
    console.info('User Credentials saved to SessionStorage');
    inp.value = '';

    React.renderComponent(
      <Library />,
      document.querySelector('#content')
    );
  },

  render: function () {
    return (
      <div className="panel panel-default">
        blabla
                  <button className="btn btn-default" type="button" onClick={this._handleSubmit} >
                    Login
                  </button>
        blabla
      </div>
    );
  }
});

这很有效,但我认为它远非最佳方法。每当我再次登录时,react都会将一个新实例从Library组件重新呈现到DOM节点中。我根本不处理解构,我觉得它很糟糕:(我知道反应不会附加,但是擦除并填充到节点中,但事件处理程序可能会保留等等。

那么对我的情况来说,什么是可能的好解决方案?

我脑子里有3种可能的解决方案

  1. 如果我与其他用户重新登录以重新呈现自己,我应该开发一个事件系统,以便能够通知Library组件,或者
  2. 我可以在登录时建立亲子关系&amp;库,所以当我修改Login组件的状态时,我的Library应用程序也会重新渲染。
  3. 调用将更新组件的操作
  4. 坚持当前
  5. :)感谢您的回答, 干杯

    提示:

    app.js

    'use strict';
    var React = require('react'),
        Login = require('./components/Login.jsx');
    
    // Dev-tools
    window.React = React;
    
    React.renderComponent(
      Login(),
      document.querySelector('#login')
    );
    

    Login.jsx

    提到上层

    Library.jsx

    /** @jsx React.DOM */
    'use strict';
    var React = require('react'),
        BookShelf = require('./BookShelf.jsx'),
        Store = require('../stores/Store'),
        Library;
    
    /**
     * Gets state from Storage
     * @returns {{books: BookCollection, users: UserCollection, categories: CategoryCollection}}
     */
    function getState() {
      var state = Store.getAll();
      return {
        books: state.books,
        users: state.users,
        categories: state.categories
      };
    }
    
    Library = React.createClass({
      getInitialState: function() {
        return getState();
      },
      componentDidMount: function() {
        Store.addChangeListener(this._onChange);
        Store.initialize();
      },
      componentWillUnmount: function() {
        Store.removeChangeListener(this._onChange);
      },
      _onChange: function() {
        this.setState(getState());
      },
      render: function() {
        return (
          <div>
            <BookShelf
              books={this.state.books}
              users={this.state.users}
              categories={this.state.categories}
            />
          </div>
        );
      }
    });
    
    module.exports = Library;
    

1 个答案:

答案 0 :(得分:5)

如果这是一个Flux应用程序,那么您希望获取所有应用程序逻辑和应用程序状态并将其移动到商店(或多个商店)。

现在,看起来您正在为与图书馆相关的事情做得很好。我会重命名该商店LibraryStore。但您可能需要AppStore或UserStore或SessionStore,或者具有与登录状态,当前用户和身份验证令牌相关的逻辑和数据的东西。

然后,一旦用户登录,是的,您可能想要创建一个Action(选项#3),让您应用中的所有不同商店知道您的用户已登录,但主要是通知AppStore。然后,您的顶级控制器视图可以监听AppStore并决定要显示的内容。如果您使用React的事件模型,则无需担心清理事件处理程序。 Flux控制器视图不使用React模型,因此我们必须清理卸载时的那些。

您的部分困难可能来自模拟异步过程。例如,身份验证将需要服务器调用,并且您的新操作将在该调用的成功/错误回调中创建。要针对localStorage进行模拟,您可以对存储进行同步查询,然后调用两个不同的操作之一进行成功/失败。