我有一个包含10个元素的div,这些元素将被逐个更新,延迟时间为2秒。下面是相同的代码
for(let boxNo=0; boxNo<10; boxNo++){
setTimeout(() => {
nodes[boxNo].isMarked = true;
this.setState({nodes});
}, (boxNo*200)+boxNo);
);
}
但是当我运行它时,所有元素都会一起更新。该程序只是添加一个延迟添加一个开始,并且所有元素都一起更新(被标记)。如何制作代码来逐一标记元素?
答案 0 :(得分:2)
您正在打破React的两个基本规则:
for(let boxNo=0; boxNo<10; boxNo++){
setTimeout(() => {
nodes[boxNo].isMarked = true; // <==== here
this.setState({nodes});
}, (boxNo*200)+boxNo);
);
}
如果根据现有状态更新状态,请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);
);
}
答案 1 :(得分:0)
setTimeout会在您的循环中首次计算200。
尝试将时间增加更多毫秒。
3秒(3000毫秒)
for(let boxNo=0; boxNo<10; boxNo++){
(function(x){
setTimeout(function(){
nodes[boxNo].isMarked = true;
this.setState({nodes});
}, ((x+1)*3000)+x);}
)(boxNo);
}
答案 2 :(得分:0)
这对我来说很好。
(function loop (boxNo) {
setTimeout(function () {
nodes[boxNo].isMarked = true;
this.setState({nodes});
if (--boxNo) loop(boxNo); // decrementing i and calling loop function again if i > 0
}, ((boxNo+1)*2000)+boxNo)
})(10);