Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

175
Visualizações
How to add, update or remove nested objects with useState

I have a possible infinite category tree and I would like to add, update or remove categories at any level with setState in react. I know this is possible with recursion but I don't have enough experience to manage this problem on my own. Here is how the data could possible look like:

const categories = [
  {
    id: "1",
    name: "category1",
    subCategories: [
      {
        id: "sub1",
        name: "subcategory1",
        subCategories: [
          { id: "subsub1", name: "subsubcategory1", subCategories: [] },
          { id: "subsub2", name: "subsubcategory2", subCategories: [] }
        ]
      },
      { id: "sub2", name: "subcategory2", subCategories: [] }
    ]
  },
  {
    id: "2",
    name: "category2",
    subCategories: []
  }
]
about 4 years ago · Santiago Gelvez
3 Respostas
Responde à pergunta

0

Considering that your top level categories object is an object and not an array, the add and remove function could be the following (same pattern for update)

function add (tree, newCategory, parentId) {
    if(tree.id === parentId) 
      return {
        ...tree,
        subCategories: tree.subCategories.concat(newCategory)
      }
    return {
        ...tree, 
        subCategories: tree.subCategories.map(c => add(c, newCategory, parentId))
    }
}



function remove (tree, idToRemove) {
        if(tree.subCategories.map(c => c.id).includes(idToRemove)) 
          return {
            ...tree,
            subCategories: tree.subCategories.filter(c => c.id !== idToRemove)
          }
        return {
            ...tree, 
            subCategories: tree.subCategories.map(c => remove(c, idToRemove))
        }
    }
about 4 years ago · Santiago Gelvez Relatório

0

this is how the recursive function would look like. the arguments:

id: id to look for

cats: the categories array to loop

nestSubCategory: (boolean) if we want to add the subcategory object in the subCategories array or not

subCategory: the category object we want to insert

const addCategories = (id, cats, nestSubCategory, subCategory)=> {
  const cat = cats.find(item=> item.id === id)
  
  const arrSubs = cats.filter(item => item.subCategories?.length)
  .map(item => item.subCategories)
 
  if(cat){
    if(nestSubCategory){
       cat.subCategories.push(subCategory)
       return
    }else{
       cats.push(subCategory)
       return
    }
  }
  
  else{
    return addCategories(id, arrSubs[0], nestSubCategory, subCategory)
  }
    
}
  

addCategories("blabla1", categories, true,  { id: "blabla2", name: "blablacategory1", subCategories: [] })
  //console.log(categories)
console.log(
  JSON.stringify(categories)
  )

remember to update the object in the state replacing the entire categories array once the function is executed. be careful with recursion 🖖🏽

you can do in a similar way to remove items, i leave to you the pleasure to experiment

about 4 years ago · Santiago Gelvez Relatório

0

Prologue

To update a nested property in an immutable way, you need to copy or perform immutable operations on all its parents.

Setting a property on a nested object:

return {
  ...parent,
  person: {
    ...parent.person,
    name: 'New Name'
  }
}

Arrays: You may pre-clone the array, or use a combination of .slice(), .map(), .filter() and the concatenation operator (...); Warning: .splice mutates the array.

(this can be a long topic, so I just gave a veryfast overview)

immer

As this can quickly get very ugly on objects with deep nesting, using the immer lib quite becomes a must at some point. Immer "creates new immutable state from mutations".

const newState = immer(oldState, draft => {
  draft[1].subcategories[3].subcategories[1].name = 'Category'
})

In the extreme case, you can combine immer with lodash to create mutations in arbitrary places:

import set from 'lodash/set'
const newState = immer(oldState, draft => {
  set(draft, [0, 'subcategories', 5, 'subcategories', 3], { id: 5, name:'Cat' })
})

"You might not need lodash" website has the recursive implementation for lodash/set. But, seriously, just use lodash.

PLUSES:

  • If you are using redux-toolkit, immer already is auto-applied on reducers, and is exposed as createNextState (check docs with care).
  • Deeply nested state can be an interesting use case for normalizr (long talk).
about 4 years ago · Santiago Gelvez Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda