É possível atualizar as propriedades do objeto setState
?
Algo como:
this.state = {
jasper: { name: 'jasper', age: 28 },
}
Eu tentei:
this.setState({jasper.name: 'someOtherName'});
e isto:
this.setState({jasper: {name: 'someothername'}})
O primeiro resulta em um erro de sintaxe e o segundo simplesmente não faz nada. Alguma ideia?
age
propriedade dentrojasper
.Respostas:
Existem várias maneiras de fazer isso, já que a atualização de estado é uma operação assíncrona ; portanto, para atualizar o objeto de estado, precisamos usar a função atualizador com
setState
.1- Um mais simples:
Primeiro, crie uma cópia
jasper
e faça as alterações:Em vez de usar
Object.assign
, também podemos escrever assim:2- Usando o operador de propagação :
Nota:
Object.assign
eSpread Operator
cria apenas uma cópia superficial , portanto, se você definiu um objeto aninhado ou uma matriz de objetos, precisará de uma abordagem diferente.Atualizando objeto de estado aninhado:
Suponha que você definiu o estado como:
Para atualizar o objeto extra de queijo de pizza:
Atualizando matriz de objetos:
Vamos supor que você tenha um aplicativo de tarefas pendentes e que esteja gerenciando os dados neste formulário:
Para atualizar o status de qualquer objeto todo, execute um mapa na matriz e verifique se há algum valor exclusivo de cada objeto; no caso
condition=true
, retorne o novo objeto com valor atualizado, caso contrário, o mesmo objeto.Sugestão: Se o objeto não tiver um valor exclusivo, use o índice da matriz.
fonte
jasper
objeto, faça oconsole.log(jasper)
que você vai ver apenas uma chavename
, idade não vai estar lá :)jasper
é umobject
, não o seja melhor ou não, pode haver outras soluções melhores são possíveis :)Object.assign
nem espalham propriedades profundas de cópia do operador. Desta forma, você deve usar soluções como lodashdeepCopy
etc.let { jasper } = this.state
?Esta é a maneira mais rápida e mais legível:
Mesmo que
this.state.jasper
já contenha uma propriedade name, o novo nomename: 'someothername'
será usado.fonte
this.state.jasper
, não contém necessariamente o estado mais recente. Melhor usar a notação com oprevState
.Use o operador spread e alguns ES6 aqui
fonte
Eu usei esta solução.
Se você tiver um estado aninhado como este:
você pode declarar a função handleChange que copia o status atual e o atribui novamente com valores alterados
aqui o html com o ouvinte de evento. Certifique-se de usar o mesmo nome usado no objeto de estado (neste caso 'friendName')
fonte
statusCopy.formInputs[inputName] = inputValue;
Sei que há muitas respostas aqui, mas estou surpreso que nenhuma delas crie uma cópia do novo objeto fora do setState e, em seguida, simplesmente setState ({newObject}). Limpo, conciso e confiável. Então, neste caso:
Ou para uma propriedade dinâmica (muito útil para formulários)
fonte
tente isso, deve funcionar bem
fonte
Object.assign({}, this.state.jasper, {name:'someOtherName'})
O primeiro caso é realmente um erro de sintaxe.
Como não consigo ver o restante do seu componente, é difícil entender por que você está aninhando objetos em seu estado aqui. Não é uma boa idéia aninhar objetos no estado do componente. Tente definir seu estado inicial como:
Dessa forma, se você deseja atualizar o nome, basta ligar para:
Isso alcançará o que você está buscando?
Para armazenamentos de dados maiores e mais complexos, eu usaria algo como Redux. Mas isso é muito mais avançado.
A regra geral com o estado do componente é usá-lo apenas para gerenciar o estado da interface do usuário do componente (por exemplo, ativo, temporizadores, etc.)
Confira estas referências:
fonte
Outra opção: defina sua variável a partir do objeto Jasper e chame apenas uma variável.
Operador de spread: ES6
fonte
Maneira simples e dinâmica.
Isso fará o trabalho, mas você precisa definir todos os IDs para o pai, para que o pai aponte para o nome do objeto, sendo id = "jasper" e nomeie o nome do elemento de entrada = propriedade dentro do objeto jasper .
fonte
Você pode tentar com isso : ( Nota : nome da tag de entrada === campo do objeto)
fonte
esta é outra solução usando o utilitário immer immutabe, muito adequado para objetos profundamente aninhados com facilidade e você não deve se preocupar com mutações
fonte
Além disso, seguindo a solução de Alberto Piras, se você não deseja copiar todo o objeto "state":
fonte
Você pode tentar com isso:
ou para outras propriedades:
Ou você pode usar a função handleChage:
e código HTML:
fonte
Sem usar Async e Aguardar Use este ...
Se você estiver usando com Async And Await, use este ...
fonte
Essa configuração funcionou para mim:
fonte