Home > database >  How to update a nested react state
How to update a nested react state

Time:06-04

I'm trying to update a react state that holds nested values. I want to update data that is 3 levels deep.

Here is the state that holds the data:

const [companies, setCompanies] = useState(companies)

Here is the data for the first company (the companies array holds many companies):

const companies = [
    {
      companyId: 100,
      transactions: [
        {
          id: "10421A",
          amount: "850",
        }
        {
          id: "1893B",
          amount: "357",
        }
    }
]

For example, I want to update the amount in the first object inside the transactions array. What I'm doing now is update the entire companies array, but doing this rerenders the whole table and creates problems. Is there a way I can only update the specific value in a manner that rerenders just the updated field in the table without rerendering the whole table? I've seen other answers but they assume that all values are named object properties.

FYI, I'm not using any state management and would prefer not to use one for now.

CodePudding user response:

You have to copy data (at least shallow copy) to update state:

const nextCompanies = { ...companies };
nextCompanies.transactions[3].amount = 357;
setState(nextCompanies);

Otherwise react won't see changes to the original object. Sure thing you can use memoization to the child component to skip useless rerenders. But I strongly recommend to provide an optimisation only when it is needed to optimise. You will make the code overcomplicated without real profit.

CodePudding user response:

When updating state based on the previous state, you probably want to pass a callback to setCompanies(). For example:

setCompanies((currCompanies) => {
  const nextCompanies = [...currCompanies];
  // modify nextCompanies
  return nextCompanies;
})

Then, in order for React to only re-render the elements that changed in the DOM, you should make sure to set the key prop in each of those elements. This way, React will know which element changed.

// inside your component code
return (
  <div>
    companies.map(company => (
        <Company key={company.id} data={company} /> 
    ))
  </div>
)

Does this solve the problem? If not, it may be helpful to add some more details so we can understand it fully.

  • Related