0

I'm struggling to modify a JSON like object with the setState property (from a useState hook). I would like to add items to labels and data arrays, at the same time.

  const dataInit = {
    labels: [
      'January',
      'February',
      'March',
      'April',
      'May',
      'June',
    ],
    datasets: [{
      label: 'My First dataset',
      backgroundColor: 'rgb(255, 99, 132)',
      borderColor: 'rgb(255, 99, 132)',
      data: [0, 10, 5, 2, 2, 30, 49,80],
    }]
  };

Here is the initialization of my useState hook with a try that doesn't work:

const [graphData, setGraphData] = useState(dataInit)

setGraphData(prevState => ({
                       ...prevState,
                       labels: prevState.labels.concat(["hey"]),
                       datasets: prevState.datasets[0].data.concat([3])
                       })
             )

Thanks for helping

skyboyer
  • 22,209
  • 7
  • 57
  • 64
Paul Lecomte
  • 141
  • 1
  • 10
  • `datasets` is an array, does it always have a single object inside ? – Gabriele Petrioli Mar 10 '22 at 19:33
  • For one, `datasets` is an array, so you need `prevState.datasets[0].data` –  Mar 10 '22 at 19:33
  • Thanks @Chris and @Gabriele. indeed `datasets` is an array, I've also tried what you are suggesting but it still doesn't work. Error message saying `prevState.datasets[0].data is undefined` – Paul Lecomte Mar 10 '22 at 19:44
  • 2
    Here's how as long as datasets has a length of 1: https://jsfiddle.net/2dcrqm8x/ There's no need to do this in a single op; you can always start to make copies of the inner objects / arrays and put the new state together from its parts. –  Mar 10 '22 at 19:50
  • Found the dupe: https://stackoverflow.com/questions/43040721/how-to-update-nested-state-properties-in-react –  Mar 10 '22 at 19:51
  • @ChrisG thanks a lot you were very helpful ! Yes indeed , it is a dupe sorry for that .. – Paul Lecomte Mar 10 '22 at 20:18
  • You're welcome :) don't worry about it –  Mar 10 '22 at 20:19

1 Answers1

0

Always return a new object to the nested props that are objects, while setting the state. What concat does is append new value to the existing object. Try something like:

const [graphData, setGraphData] = useState(dataInit)


setGraphData(prevState => 
{
    let _datasets  = [...prevState.datasets];
    _datasets[0].data = [..._datasets[0].data, ...data];
    return {
        ...prevState,
        labels: [...prevState.labels, "hey"], //new array returns with previous and new value
        datasets: _datasets
    }
})
Mujeeb Qureshi
  • 481
  • 4
  • 7
  • This is 100% a duplicate, please check for that before posting a new answer to save the mods some work. –  Mar 10 '22 at 19:50