gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 13:49:35 24 4
gpt4 key购买 nike

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

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

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

最佳答案

你违反了 React 的两条基本规则:

  1. Don't mutate state directly

    for(let boxNo=0; boxNo<10; boxNo++){
    setTimeout(() => {
    nodes[boxNo].isMarked = true; // <==== here
    this.setState({nodes});
    }, (boxNo*200)+boxNo);
    );
    }
  2. 如果根据现有状态更新状态,use the callback form因为状态更新可能是异步的(无论如何,在您的示例中,时间已经过去):

    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);
);
}

关于javascript - 即使在使用 setTimeOut 之后,setState 也会立即更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58536214/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com