我刚刚开始使用 ReactJS,但我遇到了一个问题。
我的应用程序本质上是一个带有过滤器的列表和一个用于更改布局的按钮。
目前我正在使用三个组件:<list />
, < Filters />
和<TopBar />
,现在显然当我更改 < Filters />
中的设置时我想触发<list />
中的一些方法更新我的观点。
如何使这 3 个组件相互交互,或者我是否需要某种可以进行更改的全局数据模型?
最佳答案
最好的方法取决于您计划如何安排这些组件。现在想到的一些示例场景:
-
<Filters />
是<List />
的子组件 - 两者
<Filters />
和<List />
是父组件的子组件 -
<Filters />
和<List />
完全存在于单独的根组件中。
可能还有其他我没有想到的场景。如果您的不符合这些,请告诉我。以下是我如何处理前两种情况的一些非常粗略的示例:
场景#1
您可以从 <List />
传递一个处理程序至<Filters />
,然后可以在 onChange
上调用它使用当前值过滤列表的事件。
/** @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 />
.
/** @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/