小编典典

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

reactjs

我知道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更新功能的最后一次调用不是问题,

阅读 267

收藏
2020-07-22

共1个答案

小编典典

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交互时不会发生这些改写或其他问题,但是您正在创建一种情况,其他开发人员或将来的更新可能突然发现自己遇到奇怪或微妙的问题。

2020-07-22