Javascript 如何一次设置两个数组元素的状态?

Javascript 如何一次设置两个数组元素的状态?,javascript,reactjs,ecmascript-6,Javascript,Reactjs,Ecmascript 6,我试图建立一个计时器演示应用程序。我使用setInterval自动倒计时,但我的初始状态timer是一个包含2个元素的数组,我想同时倒计时 在我的代码中,如果我将一个id参数传递到函数中(比如1或2),我就可以对一个元素进行倒计时,但我希望将每个元素一起倒计时,我如何才能做到这一点 const定时器=[ { id:1, 时间:15,, }, { id:2, 时间:20,, }, ]; 类时钟扩展了React.Component{ 建造师(道具){ 超级(道具); 此。状态={ 计时器, } }

我试图建立一个计时器演示应用程序。我使用
setInterval
自动倒计时,但我的初始状态
timer
是一个包含2个元素的数组,我想同时倒计时

在我的代码中,如果我将一个
id
参数传递到函数中(比如1或2),我就可以对一个元素进行倒计时,但我希望将每个元素一起倒计时,我如何才能做到这一点

const定时器=[
{
id:1,
时间:15,,
},
{
id:2,
时间:20,,
},
];
类时钟扩展了React.Component{
建造师(道具){
超级(道具);
此。状态={
计时器,
}
}
componentDidMount(){
设置间隔(()=>{
这是倒计时();
}, 1000);
}
倒计时(id){
const foundTimer=this.state.timers.find(timer=>timer.id==id);
foundTimer.time=foundTimer.time-1;
this.setState({timers:this.state.timers});
}
渲染器(){
返回(
this.state.timers.map((timer)=>{
控制台日志(计时器);
返回(
{timer.time}
)
})
)
}
render(){
返回(
{this.renderTimes()}
);
}
}

好的,首先,改变状态不是一个好主意,它会导致意想不到的副作用,这会让你头疼不已。这是一个很好的做法,永远不要改变国家。在不改变状态的情况下实现所需的方法如下:

...
countDown() {
  const newTimers = this.state.timers.map(t => Object.assign({}, t, { time: t.time - 1}));
  this.setState({ timers: newTimers });
}
...

好吧,首先,改变状态不是个好主意,它会导致意想不到的副作用,让你头疼不已。这是一个很好的做法,永远不要改变国家。在不改变状态的情况下实现所需的方法如下:

...
countDown() {
  const newTimers = this.state.timers.map(t => Object.assign({}, t, { time: t.time - 1}));
  this.setState({ timers: newTimers });
}
...

使用类似于将原始数组元素映射到新数组元素的
Array#map
修改
this.state.timers
。不要直接改变状态,它是所有邪恶的源头。例如:

countDown() {
  this.setState(prevState => ({
    timers: prevState.timers.map(timer => ({
      ...timer,
      time: timer.time - 1
    }))
  }));
}
这将把每个定时器映射到一个新定时器,而不改变状态,新定时器保持相同的属性(via),只是它将把每个定时器的
time
属性更改为比当前时间少1

如果您的环境不支持对象排列属性,请改用:

这将执行与上面相同的操作,它将属性从
timer
复制到空对象
{}
(防止突变),然后覆盖
time
属性并将其递减。如果您的平台不支持对象扩展属性,那么它只是一个更详细的版本


也可以考虑将<代码>计时器>代码>作为一个道具,而不是作为类之外的一个数组。将变量限制在其可能的最窄范围内。

使用类似于将原始数组元素映射到新数组元素的
修改
此.state.timer
。不要直接改变状态,它是所有邪恶的源头。例如:

countDown() {
  this.setState(prevState => ({
    timers: prevState.timers.map(timer => ({
      ...timer,
      time: timer.time - 1
    }))
  }));
}
这将把每个定时器映射到一个新定时器,而不改变状态,新定时器保持相同的属性(via),只是它将把每个定时器的
time
属性更改为比当前时间少1

如果您的环境不支持对象排列属性,请改用:

这将执行与上面相同的操作,它将属性从
timer
复制到空对象
{}
(防止突变),然后覆盖
time
属性并将其递减。如果您的平台不支持对象扩展属性,那么它只是一个更详细的版本


也可以考虑将<代码>计时器>代码>作为一个道具,而不是作为类之外的一个数组。将变量限制在尽可能狭窄的范围内。

这是一种更好的方法=D@AndrewLi我还有一个问题,如果我只想更改状态中的一个数组(如计时器的id为1),如何在不集合的情况下执行此操作?@ChamperWu如果你愿意,你可以问一个新问题,因为这超出了这个问题的范围。@AndrewLi好的,我问了另一个问题这是一个更好的方法=D@AndrewLi我还有一个问题,如果我只想更改状态中的一个数组(如计时器的id为1),我如何在不集合的情况下执行此操作?@ChamperWu如果你愿意,你可以问一个新问题,因为这超出了这个问题的范围。@AndrewLi好的,我问了另一个问题