Skip to content Skip to sidebar Skip to footer

How Can I Setstate On Two Array Elements At Once?

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

Solution 1:

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

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.

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.

Also, consider passing timers as a prop, not as an array outside the class. Restrict variables to their narrowest scope possible.

Solution 2:

Alright first of all mutating the state is not a good idea, it can lead to unexpected side effects that can give you a real headache down the line. It is a good practice to never mutate the state. A way to achieve what you want to without mutating the state can be as follows:

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

Post a Comment for "How Can I Setstate On Two Array Elements At Once?"