javascript - 如何在相关的 React 组件之间进行通信?

标签 javascript reactjs

我刚刚开始使用 ReactJS,但我遇到了一个问题。

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

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

最佳答案

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

  1. <Filters /><List /> 的子组件
  2. 两者<Filters /><List />是父组件的子组件
  3. <Filters /><List />完全存在于单独的根组件中。

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

场景#1

您可以从 <List /> 传递一个处理程序至<Filters /> ,然后可以在 onChange 上调用它使用当前值过滤列表的事件。

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 /> .

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

当组件无法在任何类型的父子关系之间进行通信时,documentation recommends setting up a global event system .

关于javascript - 如何在相关的 React 组件之间进行通信?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21285923/

相关文章:

javascript - jest-jasmine2 env.js 未处理的错误

javascript - Google map API : Display a digit in a GMarker

javascript - 淡入不同的文本行

javascript - 后退按钮、Chrome 和 DOM 更新存在严重问题

javascript - 如何在 Three.js 中获取蒙皮网格顶点的全局位置?

javascript - React Hook API,我是否需要为 SetStateAction 设置依赖?

javascript - 在另一个对象内创建动态对象

reactjs - 对于ReactJS来说,从使用Container组件和Presentation组件到使用Hooks有什么变化?

javascript - 在 DataGrid 和 ReferenceManyField 中使用 SimpleForm | react 管理员

javascript - 当用户提供反馈时禁用点击事件