0
votes

With a button click I am able to get my state to update correctly from a child component. However, the button is not very useful to me. I need the state to update from the child of a child component to the function that runs from the parent component. I am pretty new to React, but this state update is challenging me.

In the parent functional component I have the state array like this

const [totals, setTotals] = useState({
    0: 0,
    1: 0,
    2: 0,
    3: 0,
    4: 0,
    5: 0,
    6: 0,
    7: 0,
    8: 0,
    9: 0,
    10: 0,
    11: 0
});

const handleCalculations = (key, value) => {
    setTotals({
        ...totals,
        [key]:  totals[key] + value
    });
}

I am prop Drilling handleCalculations down to a child component which passes it to another child where some calculations are done and passed back to the parent through useEffect. This looks like this...

useEffect(() => {
    handleCalculations(index, paycheckCount);
}, []);

However, the state never gets updated except for the 11th index of the state array which gets 2. Could anyone please help me understand what I am doing wrong. I have included a link to a codesandbox with the full code so you can see all the code. Any help is appreciated

https://codesandbox.io/live/rwrr68f

1

1 Answers

2
votes

Issue

You pass handleCalculations to Row which passes it to DateField/TableCell within a loop, and TableCell invokes it upon component mounting. You've effectively enqueued a bunch of state updates in a loop and they all update from the same current state of the render cycle they are enqueued in.

Solution

Use a functional state update to enqueue each update and have each one update from the previous computed state, not the state from the previous render cycle.

const handleCalculations = (key, value) => {
  console.log(key);
  console.log(value);
  setTotals(totals => ({
    ...totals,
    [key]: totals[key] + value
  }));
};

Note: This appears to cause an invalid numerical computation, so you can guard against NaN with [key]: totals[key] + value || 0. I think this is due to you mixing using a mapped index and object keys, i.e. your totals state is an object but it isn't zero-indexed like an array would be.

Edit useeffect-not-updating-state