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

即使使用setTimeOut之后,setState也会立即更新

柳坚白
2023-03-14
问题内容

我有一个包含10个元素的div,这些元素将被逐个更新,延迟时间为2秒。下面是相同的代码

    for(let boxNo=0; boxNo<10; boxNo++){
      setTimeout(() => {
        nodes[boxNo].isMarked = true;
        this.setState({nodes});
        }, (boxNo*200)+boxNo);
      );
    }

但是,当我运行它时,所有元素都会一起更新。该程序只是添加一个延迟添加一个开始,并且所有元素都一起更新(被标记)。如何制作代码来逐一标记元素?


问题答案:

您正在打破React的两个基本规则:

  1. 不要直接改变状态
        for(let boxNo=0; boxNo<10; boxNo++){
      setTimeout(() => {
        nodes[boxNo].isMarked = true; // <==== here
        this.setState({nodes});
        }, (boxNo*200)+boxNo);
      );
    }
  1. 如果根据现有状态更新状态,请使用回调形式,因为状态更新可能是异步的(无论如何,在您的示例中,时间已经过去了):
        for(let boxNo=0; boxNo<10; boxNo++){
      setTimeout(() => {
        nodes[boxNo].isMarked = true;
        this.setState({nodes});       // <==== here
        }, (boxNo*200)+boxNo);
      );
    }

相反,请参见***注释和相关代码:

    // **IF** `nodes` is an array
    for(let boxNo=0; boxNo<10; boxNo++){
      setTimeout(() => {
        // *** Note using callback form (#2)
        this.setState(({nodes} => {
            // *** *Copy* the parts of state you're going to modify (#1)
            nodes = [...nodes];
            nodes[boxNo] = {...nodes[boxNo], isMarked: true};
            return {nodes};
        });
        }, (boxNo*200)+boxNo);
      );
    }

setState调用也可以这样编写,但 要花 一些时间 创建临时对象):

    this.setState(({nodes} => ({
        nodes: Object.assign([], nodes, {[boxNo]: {...nodes[boxNo], isMarked: true}})
    });

要么

    // **IF** `nodes` is a non-array object
    for(let boxNo=0; boxNo<10; boxNo++){
      setTimeout(() => {
        // *** Note using callback form (#2)
        this.setState(({nodes} => {
            // *** *Copy* the parts of state you're going to modify (#1)
            return {
                nodes: {
                    ...nodes,
                    [boxNo]: {...nodes[boxNo], isMarked: true}
                }
            };
        });
        }, (boxNo*200)+boxNo);
      );
    }


 类似资料:
  • 我想问一下,为什么在执行事件时,我的状态没有改变。我已经搜索到需要在构造函数中绑定函数,但是状态仍然没有更新。 下面是我的代码:

  • 问题内容: 我想问为什么在执行onclick事件时状态没有变化。我已经搜索了一段时间,我需要在构造函数中绑定onclick函数,但状态仍未更新。这是我的代码: 问题答案: 这个回调真的很混乱。只需使用async await代替:

  • 问题内容: 我想问一下为什么在执行onclick事件时状态没有变化。我已经搜索了一段时间,我需要在构造函数中绑定onclick函数,但状态仍未更新。这是我的代码: 问题答案: 幸运的是, setState进行了回调。这是我们获取更新状态的地方。考虑这个例子。 因此,当回调触发时,this.state是更新后的状态。你可以在回调中获取突变/更新的数据。

  • 我正在创建一个如下所示的JobDetail,

  • 问题内容: 我正在做一个待办事项应用程序。这是违规代码的非常简化的版本。我有一个复选框: 这是调用复选框的函数: updateItem是映射为分派到redux的函数 我的问题是,当我调用updateItem操作并在console.log状态时,它总是落后1步。如果未选中该复选框且该复选框不为true,则仍将状态为true传递给updateItem函数。我是否需要调用另一个函数来强制状态更新? 问题

  • 我有一个简单的组件 问题是我需要添加什么