当前位置: 首页 > 面试题库 >

实际上,为什么我不能直接修改组件的状态?

公冶麒
2023-03-14
问题内容

我知道,React教程和文档毫无疑问地警告说,状态不应该直接变异,所有事情都应该通过setState

我想了解一下,为什么我不能直接更改状态,然后(在同一函数中)调用this.setState({})仅触发render

例如:以下代码似乎正常工作:

const React = require('react');

const App = React.createClass({
    getInitialState: function() {
        return {
            some: {
                rather: {
                    deeply: {
                        embedded: {
                            stuff: 1
                        }}}}};
    },
    updateCounter: function () {
        this.state.some.rather.deeply.embedded.stuff++;
        this.setState({}); // just to trigger the render ...
    },
    render: function() {
        return (
                <div>
                Counter value: {this.state.some.rather.deeply.embedded.stuff}
                <br></br>
                <button onClick={this.updateCounter}>inc</button>
                </div>
        );
    }
});

export default App;

我全都遵循以下约定,但是我想进一步加深对ReactJS实际工作方式的理解,以及可能出现问题的地方或上述代码的最佳选择。

下的笔记this.setState文档基本上识别两个陷阱:

  1. 如果您直接更改状态,然后再调用this.setState它,则可能会替换(覆盖?)所做的更改。我看不到上面的代码中如何发生这种情况。
  2. setState可能会this.state以异步/延迟的方式有效地进行更改,因此this.state在调用后this.setState立即访问时,不能保证您访问最终的更改状态。我知道,如果this.setState更新函数的最后一次调用不是问题,

问题答案:

React文档setState对此有这样的说法:

切勿this.state直接进行突变,因为setState()随后的呼叫可能会取代您所做的突变。对待this.state就好像它是不可变的。

setState()不会立即变异,this.state但会创建待处理的状态转换。this.state调用此方法后进行访问可能会返回现有值。

无法保证对呼叫的同步操作,setState并且可以为提高性能而对呼叫进行批量处理。

setState()除非在中实现了条件渲染逻辑,否则它将始终触发重新渲染shouldComponentUpdate()。如果正在使用可变对象,并且无法在中实现逻辑shouldComponentUpdate(),则setState()仅在新状态与先前状态不同时进行调用才能避免不必要的重新渲染。

基本上,如果this.state直接进行修改,则会造成一种情况,即这些修改可能会被覆盖。

与您的扩展问题1)和2)有关,setState()不是立即的。
它根据其正在进行的状态对状态转换进行排队,该状态转换可能不包括对的直接更改this.state。由于已排队而不是立即应用,因此完全有可能在两者之间进行某些修改,以使您的直接更改被覆盖。

如果没有别的,您可能会觉得更好,只是考虑将不直接修改this.state视为良好做法。您可能个人知道您的代码与React交互时不会发生这些覆盖或其他问题,但是您正在创建一种情况,其他开发人员或将来的更新可能突然发现自己遇到奇怪或微妙的问题。



 类似资料:
  • 问题内容: 我知道React教程和文档毫无疑问地警告说,状态不应该直接变异,所有事情都应该通过。 我想了解一下,为什么我不能直接更改状态,然后(在同一函数中)仅调用来触发它。 例如:下面的代码似乎正常工作: 我全都遵循以下约定,但我想进一步加深对ReactJS实际工作方式的理解,以及可能出现问题的地方或上述代码的优缺点。 文档下的注释基本上标识了两个陷阱: 如果您直接更改状态,然后再调用它,则可能

  • 本文向大家介绍React为什么不要直接修改state?如果想修改怎么做?相关面试题,主要包含被问及React为什么不要直接修改state?如果想修改怎么做?时的应答技巧和注意事项,需要的朋友参考一下 不能直接修改state,组件修改state,并不会重新触发render. state的更新是异步的,调用setState时,组件state并不会立即改变,只是把要修改的状态放入事件队列当中. this

  • 我使用Apache POI工作簿在Java中打开一个Excel文件(源代码),更改某一组单元格中的数据,将工作簿保存到一个单独的文件中,然后关闭工作簿(因为文档中规定关闭工作簿,即使它是只读的)。 POI每次都会更改源Excel文件中的数据。根据POI文档中的建议,我尝试了几种不同的方法来防止这种情况,但这些方法都失败了。 这里有两种尝试在理论上应该有效,但没有。 尝试1-将源文件设置为只读 在W

  • 我使用dropwizard制作了一个非常传统的文件上传方法。 所以我在资源中有一个这样的方法 里面没有什么特别的,它只是保存到一个路径,使用java.nio库,就像这样 它只是不会上传excel文件。我在其他地方读到excel文件和它们的底层类型受到怀疑。请问我需要做什么?

  • 问题内容: 新手有问题,请保持温柔: 结果是: 我不明白为什么列表改变时,我只是在做,没有。我什至不知道要用什么搜索词来弄清楚。 问题答案: 这是因为在进行分配后,和都引用相同的列表。 尝试执行以下操作以查看它们是指相同的对象还是不同的对象: 一个例子: 如果您确实要创建这样的重复副本,而不是引用原始列表,而是引用列表的副本,请使用slice运算符: 一个例子: 另外,请勿将其用作变量名,因为最初

  • 基本上,我试图用一个名为“a”的变量设置数组的长度,并将其声明为3和int。当我试图用for循环查看所有元素时,我不会将“null”作为元素。到现在为止,一直都还不错。然而,当有人想向该数组中添加一个元素时,我会向提到的变量“a”中添加1,从而延长该数组的长度,并允许我向该数组中再添加一个元素。但它不起作用。以下是代码: }