2

I have an array tranches: [{ start: moment().format("HH:mm"), end: moment().format("HH:mm") }] and when I set the value of the tranches[0].start without setState I get :

Do not mutate state directly. Use setState()

My code is :

handleAjouter = (start, end, date) => {
    this.state.tranches[0].start = start;
    this.state.tranches[0].end = end;
    this.setState({
      tranches: this.state.tranches
    });
  }

How can I fix it ?

Ichrak Mansour
  • 1,850
  • 11
  • 34
  • 61

1 Answers1

4

Clone the tranches[0] object instead of mutating it, which you can achieve concisely with object spread:

handleAjouter = (start, end, date) => {
  const [firstTranch] = this.state.tranches;
  this.setState({
    tranches: [
      { ...firstTranch, start, end },
      ...tranches.slice(1)  // needed if the array can contain more than one item
    ]
  });
}

If you need to insert the changed tranch at a specific index, then clone the array and insert the tranch:

const tranches = this.state.tranches.slice();
tranches[index] = { ...tranches[index], someOtherProp: 'foo' };
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • Thank you @CertainPerformance, and what about when I have `this.state.tranches[selectedIndex] = { ...this.state.tranches[selectedIndex], [startOrEnd]: textValue };` – Ichrak Mansour May 15 '19 at 09:55
  • 1
    Slice the whole array first, and then you can reassign the element at the desired index – CertainPerformance May 15 '19 at 10:00
  • I try const `tranches = this.state.tranches.slice(); tranches[selectedIndex] = { ...tranches[selectedIndex], [startOrEnd]: textValue }; this.setState({ tranches:this.state.tranches });` But it doesn't working. – Ichrak Mansour May 15 '19 at 10:06
  • 1
    You set the new state to exactly the same thing as the old state. Call `setState` with the *new* `tranches` array instead. `this.setState({ tranches });` – CertainPerformance May 15 '19 at 10:12