如何一次就可以在两个数组元素上setState? [英] How can I setState on two array elements at once?
问题描述
我试图建立一个定时演示应用程序。我使用 setInterval
来自动计数定时器,但是我的初始状态 timer
是一个有2个元素的数组,想在这两个计时器上统计下来。
I tried to build a Timer Demo App. I used setInterval
to auto count down the timer, but my initial state timer
is an array with 2 elements, and I want to count down on both timers together.
在我的代码中,只要我传递一个 id
参数到函数(如1或2),但是我想要一起倒数,我该怎么办?
In my code I just can count down one element if I pass an id
argument into the function (like 1 or 2), but I want count down each together, how can I go about doing this?
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>
);
}
}
推荐答案
修改 this.state.timers
,其中包含将原始数组元素映射到新元素的 Array#map
。不要直接改变国家,这是所有邪恶的根源。例如:
Modify this.state.timers
with something like Array#map
that maps original array elements to new ones. Don't mutate state directly, it's the source of all evil. For example:
countDown() {
this.setState(prevState => ({
timers: prevState.timers.map(timer => ({
...timer,
time: timer.time - 1
}))
}));
}
这将映射每个定时器到一个新的定时器,而不会突变状态,新定时器保留相同的属性(通过对象传播属性),除了它将每个定时器的时间
属性更改为1当前时间。
This will map each of the timers to a new timer, without mutating state, where the new timers keep the same properties (via object spread properties) except it will change the time
property of every timer to 1 less the current time.
如果对象传播属性不是在您的环境中支持,请使用 Object.assign
:
If object spread properties isn't supported in your environment, use Object.assign
instead:
this.setState(prevState => ({
timers: prevState.timers.map(timer =>
Object.assign(
{},
timer,
{ time: timer.time - 1 }
)
)
}));
这将做同样的确切的事情,它将从定时器
转换为空对象 {}
(防止突变),然后覆盖时间
属性并减少它。如果您的平台不支持对象传播属性,它只是一个更详细的版本。
This will do the same exact thing above, it will copy the properties from timer
into an empty object {}
(preventing mutation), then overriding the time
property and decrementing it. It's just a more verbose version if your platform doesn't support object spread properties.
另外,考虑传递 timers
as a prop ,而不是类之外的数组。限制变量到最窄范围。
Also, consider passing timers
as a prop, not as an array outside the class. Restrict variables to their narrowest scope possible.
这篇关于如何一次就可以在两个数组元素上setState?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!