ReactJS:具有嵌套组件的大型应用程序

时间:2014-09-15 12:14:47

标签: reactjs reactjs-flux

我正在开发一个包含许多嵌套状态和组件的大型ReactJS应用程序。我希望大多数组件可以独立开发。考虑有两个组成部分:

  1. 通用自动建议文本框(例如,它建议用户)
  2. 表单组件,其中我使用自动建议组件
  3. 在应用程序级别,我有UserStore,Dispatcher和UserActions。所以我的问题是

    1. 如果单独开发自动建议,它如何使用应用程序级别调度程序?或者组件是否应该有另一组UserStore,Dispatcher和UserActions?
    2. 如果表单组件是独立开发的,那么它将如何从自动建议组件接收数据?

1 个答案:

答案 0 :(得分:4)

通过要求单独开发,您基本上要求在多个上下文中使用相同的组件。无论如何,将它构建为能够在多个上下文中工作是一个好主意,这样您就可以在多个位置或多个应用程序中重用组件。

但要做到这一点,你必须传递特定于应用程序的所有东西作为道具。值得注意的是,这包括通常会调用应用程序的动作创建者的事件处理程序。

您可以通过在闭包中开发组件来伪造您的调度程序和操作创建者。您可能希望将用户数据作为道具传递,也传递给您的事件处理程序。在真正的Flux应用程序中,您将拥有一个控制器视图组件,该组件从UserStore获取数据并将该数据传递到您的组件中。因此,调度程序,操作和控制器视图都将被关闭所伪造。

不是使用真正的调度程序和操作,而是只需要简单的事情来更新闭包中的状态。所以你的开发平台看起来像这样:

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

var container = document.getElementById('development-container');

var users = [
  { id: '1', name: 'Joey' },
  { id: '2', name: 'Johnny' },
  { id: '3', name: 'Dee Dee' },
  { id: '4', name: 'Tommy' }
];

var onKeyDown = function() { 
  // do stuff with users
  render(container);
}

var render = function(container) {
  React.renderComponent(
    <AutoSuggest
       users={users}
       onKeyDown={onKeyDown}
    />,
    container
  );
};
render(container);

然后您的真实生产代码可能类似于:

var React = require('react');
var AutoSuggest = require('AutoSuggest');
var UserStore = require('UserStore');
var UserActions = require('UserActions');

function onKeyDown(e) {
  UserActions.doSomething(e.value);
}

var SomeControllerView = React.createClass({

  getInitialState: function() {
    return {
      users: UserStore.getAll();
    };
  },

  componentWillMount: function() {
    UserStore.addListener('change', this.onChange.bind(this));
  },

  render: function() {
    return (
      <AutoSuggest 
        users={this.state.users}
        onKeyDown={onKeyDown} 
      />
    );
  },

  componentWillUnmount: function() {
    UserStore.removeListener('change', this.onChange);
  },

  onChange: function() {
    this.setState({ 
      users: UserStore.getAll() 
    });
  }    

});

module.exports = SomeControllerView;