ReactJS两个组件进行通信 [英] ReactJS Two components communicating

查看:42
本文介绍了ReactJS两个组件进行通信的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚开始使用ReactJS,对我遇到的问题有些困惑.

I just got started with ReactJS and am a little stuck on a problem that I have.

我的应用程序本质上是一个包含过滤器和更改布局的按钮的列表. 目前,我正在使用三个组件:<list />< Filters /><TopBar />,现在显然当我更改< Filters />中的设置时,我想触发<list />中的某些方法来更新我的视图.

My application is essentially a list with filters and a button to change the layout. At the moment I'm using three components: <list />, < Filters /> and <TopBar />, now obviously when I change settings in < Filters /> I want to trigger some method in <list /> to update my view.

如何使这三个组件相互交互,或者我需要可以对其进行更改的某种全局数据模型?

How can I make those 3 components interact with each other, or do I need some sort of global data model where I can just make changes to?

推荐答案

最好的方法取决于您计划如何安排这些组件.现在想到的一些示例场景:

The best approach would depend on how you plan to arrange those components. A few example scenarios that come to mind right now:

  1. <Filters /><List />
  2. 的子组件
  3. <Filters /><List />都是父级组件的子级
  4. <Filters /><List />完全位于单独的根组件中.
  1. <Filters /> is a child component of <List />
  2. Both <Filters /> and <List /> are children of a parent component
  3. <Filters /> and <List /> live in separate root components entirely.

可能还有其他我没有想到的情况.如果您的不适合这些,请告诉我.以下是一些有关如何处理前两种情况的非常粗糙的示例:

There may be other scenarios that I'm not thinking of. If yours doesn't fit within these, then let me know. Here are some very rough examples of how I've been handling the first two scenarios:

您可以将处理程序从<List />传递给<Filters />,然后可以在onChange事件上调用该处理程序,以使用当前值过滤列表.

You could pass a handler from <List /> to <Filters />, which could then be called on the onChange event to filter the list with the current value.

JSFiddle for#1→

/** @jsx React.DOM */

var Filters = React.createClass({
  handleFilterChange: function() {
    var value = this.refs.filterInput.getDOMNode().value;
    this.props.updateFilter(value);
  },
  render: function() {
    return <input type="text" ref="filterInput" onChange={this.handleFilterChange} placeholder="Filter" />;
  }
});

var List = React.createClass({
  getInitialState: function() {
    return {
      listItems: ['Chicago', 'New York', 'Tokyo', 'London', 'San Francisco', 'Amsterdam', 'Hong Kong'],
      nameFilter: ''
    };
  },
  handleFilterUpdate: function(filterValue) {
    this.setState({
      nameFilter: filterValue
    });
  },
  render: function() {
    var displayedItems = this.state.listItems.filter(function(item) {
      var match = item.toLowerCase().indexOf(this.state.nameFilter.toLowerCase());
      return (match !== -1);
    }.bind(this));

    var content;
    if (displayedItems.length > 0) {
      var items = displayedItems.map(function(item) {
        return <li>{item}</li>;
      });
      content = <ul>{items}</ul>
    } else {
      content = <p>No items matching this filter</p>;
    }

    return (
      <div>
        <Filters updateFilter={this.handleFilterUpdate} />
        <h4>Results</h4>
        {content}
      </div>
    );
  }
});

React.renderComponent(<List />, document.body);


场景#2

类似于场景1,但是父组件将是向下传递处理程序函数到<Filters />的组件,并将过滤后的列表传递给<List />.我更喜欢这种方法,因为它可以将<List /><Filters />解耦.


Scenario #2

Similar to scenario #1, but the parent component will be the one passing down the handler function to <Filters />, and will pass the filtered list to <List />. I like this method better since it decouples the <List /> from the <Filters />.

JSFiddle for#2→

/** @jsx React.DOM */

var Filters = React.createClass({
  handleFilterChange: function() {
    var value = this.refs.filterInput.getDOMNode().value;
    this.props.updateFilter(value);
  },
  render: function() {
    return <input type="text" ref="filterInput" onChange={this.handleFilterChange} placeholder="Filter" />;
  }
});

var List = React.createClass({
  render: function() {
    var content;
    if (this.props.items.length > 0) {
      var items = this.props.items.map(function(item) {
        return <li>{item}</li>;
      });
      content = <ul>{items}</ul>
    } else {
      content = <p>No items matching this filter</p>;
    }
    return (
      <div className="results">
        <h4>Results</h4>
        {content}
      </div>
    );
  }
});

var ListContainer = React.createClass({
  getInitialState: function() {
    return {
      listItems: ['Chicago', 'New York', 'Tokyo', 'London', 'San Francisco', 'Amsterdam', 'Hong Kong'],
      nameFilter: ''
    };
  },
  handleFilterUpdate: function(filterValue) {
    this.setState({
      nameFilter: filterValue
    });
  },
  render: function() {
    var displayedItems = this.state.listItems.filter(function(item) {
      var match = item.toLowerCase().indexOf(this.state.nameFilter.toLowerCase());
      return (match !== -1);
    }.bind(this));

    return (
      <div>
        <Filters updateFilter={this.handleFilterUpdate} />
        <List items={displayedItems} />
      </div>
    );
  }
});

React.renderComponent(<ListContainer />, document.body);


场景#3

当组件无法在任何类型的父子关系之间进行通信时,文档建议建立全球事件系统.


Scenario #3

When the components can't communicate between any sort of parent-child relationship, the documentation recommends setting up a global event system.

这篇关于ReactJS两个组件进行通信的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆