在 React JS 中,什么时候应该使用 store 还是直接操作视图的状态?
In React JS, when should you use a store vs directly manipulating the view's state?
现在我明白商店的概念是 React 应用程序的真实来源,但有时使用商店似乎有点矫枉过正,尤其是在 UI-only 情况下。
例如,假设我正在制作一个包含电影列表的应用程序。该应用程序包含一个搜索栏,可让您根据标题过滤这些电影。这个搜索栏的值(我们称之为 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()
函数中执行过滤?
两种方法都是正确的!但是对于您的情况,在组件中过滤更好。因为搜索结果是可以计算的。商店应该只保留原始数据。 "Developing the React edge" 书上有一个 filterableForm 的例子,在视图组件中保留搜索关键字是完全可以的。
如您的示例所示,不使用商店更简单,并且在这种情况下可以说是正确的。
要回答的问题是:
Does any other component need to know about the search results?
更好的问题是:
Might some other component need to know about the search results?
考虑一下,如果您在结果中添加分页,或者甚至是“找到 12 个结果”的简单 header,那么这些组件需要知道结果并且需要从存储中获取它。或者您可能想要添加路由器并让搜索更新 url 和 url 更改以驱动应用程序。
如果您可以肯定地说只有子组件会关心某个值,那么状态就可以了。
现在我明白商店的概念是 React 应用程序的真实来源,但有时使用商店似乎有点矫枉过正,尤其是在 UI-only 情况下。
例如,假设我正在制作一个包含电影列表的应用程序。该应用程序包含一个搜索栏,可让您根据标题过滤这些电影。这个搜索栏的值(我们称之为 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()
函数中执行过滤?
两种方法都是正确的!但是对于您的情况,在组件中过滤更好。因为搜索结果是可以计算的。商店应该只保留原始数据。 "Developing the React edge" 书上有一个 filterableForm 的例子,在视图组件中保留搜索关键字是完全可以的。
如您的示例所示,不使用商店更简单,并且在这种情况下可以说是正确的。
要回答的问题是:
Does any other component need to know about the search results?
更好的问题是:
Might some other component need to know about the search results?
考虑一下,如果您在结果中添加分页,或者甚至是“找到 12 个结果”的简单 header,那么这些组件需要知道结果并且需要从存储中获取它。或者您可能想要添加路由器并让搜索更新 url 和 url 更改以驱动应用程序。
如果您可以肯定地说只有子组件会关心某个值,那么状态就可以了。