我尝试构建一个计时器演示应用程序。我使用 setInterval
自动倒计时计时器,但我的初始状态 timer
是一个包含 2 个元素的数组,我想同时对两个计时器进行倒计时.
在我的代码中,如果我将 id
参数传递给函数(例如 1 或 2),我只能倒数一个元素,但我想一起倒数每个元素,我该怎么做这个?
const timers = [
{
id: 1,
time: 15,
},
{
id: 2,
time: 20,
},
];
class Clock extends React.Component {
constructor(props) {
super(props);
this.state= {
timers,
}
}
componentDidMount(){
setInterval(() => {
this.countDown();
}, 1000);
}
countDown(id){
const foundTimer = this.state.timers.find(timer => timer.id === id);
foundTimer.time = foundTimer.time - 1;
this.setState({timers: this.state.timers});
}
renderTimers(){
return(
this.state.timers.map((timer) =>{
console.log(timer);
return(
<div key = {timer.id} >
<div>{timer.time}</div>
</div>
)
})
)
}
render() {
return (
<div>
{this.renderTimers()}
</div>
);
}
}
最佳答案
使用Array#map
之类的内容修改this.state.timers
,将原始数组元素映射到新元素。不要直接改变状态,它是万恶之源。例如:
countDown() {
this.setState(prevState => ({
timers: prevState.timers.map(timer => ({
...timer,
time: timer.time - 1
}))
}));
}
这会将每个计时器映射到一个新计时器,而不改变状态,其中新计时器保持相同的属性(通过 object spread properties ),除了它会更改每个计时器的 time
属性当前时间减 1。
如果您的环境不支持对象传播属性,请使用 Object.assign
相反:
this.setState(prevState => ({
timers: prevState.timers.map(timer =>
Object.assign(
{},
timer,
{ time: timer.time - 1 }
)
)
}));
这将执行与上面完全相同的操作,它将属性从 timer
复制到空对象 {}
(防止突变),然后覆盖 time
属性并递减它。如果您的平台不支持对象传播属性,这只是一个更详细的版本。
此外,请考虑将 timers
作为 prop 传递,而不是作为类外部的数组传递。将变量限制在尽可能小的范围内。
关于javascript - 如何同时在两个数组元素上设置状态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45257033/