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

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

陈畅
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

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

  • 我正在尝试将ArrayList添加到Jlist,但我给出的唯一理解方法是编写如下代码: 让我困惑的是,为什么我不能像这样直接把数组列表添加到Jlist中: 先谢谢你。

  • 问题内容: 我熟悉Tkinter,并且尝试编写一个非常简单的程序,该程序使用包几何管理器在窗口中显示一个按钮。 我与各种配置选项试验,如,和,和我碰到一个特殊的问题。我写了以下代码: 问题在于按钮会在水平方向(而不是垂直方向)上展开以填充窗口。如果没有指定我使用,则得到的结果相同。另外,如果我指定的话,按钮不会向任一方向扩展。垂直方向上的填充似乎出了问题,我无法弄清楚它可能是什么。 我尝试使用Go