现在我理解了商店的概念是 React 应用程序的事实来源,但有时使用商店似乎有点矫枉过正,尤其是在仅限 UI 的情况下。
例如,假设我正在制作一个包含电影列表的应用程序。该应用程序包含一个搜索栏,可让您根据标题过滤这些电影。这个搜索栏的值(我们称之为searchTerm
)应该包含在商店中吗?它唯一的影响是显示的电影列表,这纯粹是一个 UI 功能。它不会发送到服务器或保存到本地存储。因此,在我的handleTextChange
函数中,我应该提醒商店,还是简单地设置组件的状态:
应该是这个(使用商店):
var Actions = Reflux.createActions([
"searchChanged"
]);
var Store = Reflux.createStore({
listenables: [Actions],
getInitialState: function () {
return data;
},
onSearchChanged: function (searchTerm) {
this.trigger(data.filter(function (el) {
return el.name.toLowerCase().indexOf(searchTerm.toLowerCase()) != -1;
}));
}
});
var View = React.createClass({
mixins: [Reflux.connect(Store, "movies")],
handleTextChange: function (e) {
Actions.searchChanged(e.target.value);
},
render: function(){
//Render here. Somewhere there is this input element:
<input onChange={this.handleTextChange} type="text"/>
}
)};
或者这个(不使用商店):
var Store = Reflux.createStore({
getInitialState: function () {
return data;
},
});
var View = React.createClass({
mixins: [Reflux.connect(Store, "movies")],
handleTextChange: function (e) {
this.setState({searchTerm: e.target.value});
},
render: function(){
var filtered = this.movies.filter(function (el) {
return el.name.toLowerCase().indexOf(this.state.searchTerm.toLowerCase()) != -1;
});
//Render here using the filtered variable. Somewhere there is this input element:
<input onChange={this.handleTextChange} type="text"/>
}
}
后一个例子显然更简单。是否有充分的理由使用存储来筛选数据?还是视图应该有一个searchTerm
变量并在render()
函数中执行过滤?
正如您的示例所示,不使用商店更简单,在这种情况下可以说是正确的。
要回答的一个弱问题是:
是否有任何其他组件需要了解搜索结果?
一个更好的问题是:
其他组件是否需要了解搜索结果?
请考虑一下,如果您添加对结果的分页,甚至是"找到 12 个结果"的简单标头,则这些组件需要知道结果,并且需要从存储中获取结果。或者,您可能希望添加路由器并让搜索更新 url 并更改 url 以驱动应用程序。
如果你可以肯定地说只有子组件会关心一个值,那么状态是可以的。
这两种方法都是正确的!但对于您的情况,在组件中过滤会更好。因为搜索结果是可计算的。存储应仅保留原始数据。"开发 React 边缘"一书有一个 filterableForm 的例子,将搜索关键字保留在视图组件中是完全可以的。