在 React JS 中,啥时候应该使用存储与直接操作视图的状态?

Posted

技术标签:

【中文标题】在 React JS 中,啥时候应该使用存储与直接操作视图的状态?【英文标题】:In React JS, when should you use a store vs directly manipulating the view's state?在 React JS 中,什么时候应该使用存储与直接操作视图的状态? 【发布时间】:2015-05-18 11:47:11 【问题描述】:

现在我将 store 的概念理解为 React 应用程序的真实来源,但似乎有时使用 store 是多余的,尤其是在仅 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() 函数中执行过滤?

【问题讨论】:

取决于您在存储中缓存数据的方式。在某些时候,您可能希望使用您的 searchTerm 过滤数据。您可以在组件中执行此操作,让商店知道搜索了哪个 searchTerm,或者在获取数据时将其作为参数发送。我喜欢不向他们不需要的组件发送太多信息。所以尽早过滤是我用过的一种方法,但不能说什么是最好的方法。如果数据集很小,真的不需要缓存数据,组件过滤就可以了。 【参考方案1】:

正如您的示例所示,不使用商店更简单,并且在这种情况下可以说是正确的。

要回答的弱问题是:

是否有任何其他组件需要了解搜索结果?

一个更好的问题是:

可能其他组件需要了解搜索结果吗?

考虑一下,如果您添加对结果的分页,甚至是“找到 12 个结果”的简单标题,那么这些组件需要知道结果并且需要从商店中获取结果。或者您可能想要添加一个路由器并让搜索更新 url,并更改 url 以驱动应用程序。

如果你可以肯定地说只有子组件会关心一个值,那么状态就可以了。

【讨论】:

【参考方案2】:

这两种方法都是正确的!但是对于您的情况,在组件中进行过滤会更好。因为搜索结果是可计算的。商店应该只保留原始数据。 《Developing the React edge》一书中有filterableForm的例子,在视图组件中保留搜索关键字就可以了。

【讨论】:

以上是关于在 React JS 中,啥时候应该使用存储与直接操作视图的状态?的主要内容,如果未能解决你的问题,请参考以下文章

react.js在服务器端渲染有啥好处?渲染是怎么个流程

React Context API 和单独的 JS 文件来存储用户数据有啥不同?

React/Redux - 你啥时候应该从 API 获取新数据来更新你的商店?

我想在反应中缓存图像,我应该使用啥来存储

我啥时候应该在“class”上使用“className”,反之亦然?

我啥时候应该在独立的 node.js 上使用 express.js