É possível actualizar as propriedades do objecto's com o setState?
Algo do género:
this.state = {
jasper: { name: 'jasper', age: 28 },
}
Eu já tentei:
this.setState({jasper.name: 'someOtherName'});
e isto:
this.setState({jasper: {name: 'someothername'}})
O primeiro resulta num erro de sintaxe e o segundo simplesmente não faz nada. Alguma ideia?
Existem várias maneiras de fazer isso, já que a atualização do estado é uma async operation, então para atualizar o objeto estado, precisamos utilizar função atualizadora com setState
.
1- A mais simples:
Primeiro crie uma cópia do 'jasper' e depois faça as alterações nele:
this.setState(prevState => {
let jasper = Object.assign({}, prevState.jasper); // creating copy of state variable jasper
jasper.name = 'someothername'; // update the name property, assign a new value
return { jasper }; // return new object jasper object
})
Em vez de utilizarmos `Object.assign' podemos também escrevê-lo desta forma:
let jasper = { ...prevState.jasper };
**2- Usando spread operator***:
this.setState(prevState => ({
jasper: { // object that we want to update
...prevState.jasper, // keep all other key-value pairs
name: 'something' // update the value of specific key
}
}))
Note: Object.assign
e Spread Operator
cria apenas cópia rasa, então se você tiver definido objeto aninhado ou array de objetos, você precisa de uma abordagem diferente.
Suponha que você tenha definido o estado como:
this.state = {
food: {
sandwich: {
capsicum: true,
crackers: true,
mayonnaise: true
},
pizza: {
jalapeno: true,
extraCheese: false
}
}
}
Para actualizar o objecto extraCheese de pizza:
this.setState(prevState => ({
food: {
...prevState.food, // copy all other key-value pairs of food object
pizza: { // specific object of food object
...prevState.food.pizza, // copy all pizza key-value pairs
extraCheese: true // update value of specific key
}
}
}))
Vamos assumir que você tem um aplicativo completo, e que você está gerenciando os dados neste formulário:
this.state = {
todoItems: [
{
name: 'Learn React Basics',
status: 'pending'
}, {
name: 'Check Codebase',
status: 'pending'
}
]
}
Para atualizar o status de qualquer objeto todo, execute um mapa no array e verifique se há algum valor único de cada objeto, no caso de condição=verdadeiro
, devolva o novo objeto com valor atualizado, caso contrário, o mesmo objeto.
let key = 2;
this.setState(prevState => ({
todoItems: prevState.todoItems.map(
el => el.key === key? { ...el, status: 'done' }: el
)
}))
Sugestão: Se o objeto não't tem um valor único, então use o índice de array.
O primeiro caso é de facto um erro de sintaxe.
Como eu posso'não vejo o resto do seu componente, é'é difícil ver porque você'está aninhando objetos no seu estado aqui. It'não é uma boa ideia nidificar objectos em estado de componente. Tente definir o seu estado inicial para ser:
this.state = {
name: 'jasper',
age: 28
}
Assim, se você quiser atualizar o nome, basta ligar:
this.setState({
name: 'Sean'
});
Será que isso vai alcançar o que você'está a tentar alcançar?
Para grandes e mais complexos armazéns de dados, eu usaria algo como Redux. Mas isso'é muito mais avançado.
A regra geral com o estado do componente é usá-lo apenas para gerir o estado do componente (por exemplo, activo, temporizadores, etc.)
Confira estas referências:
Outra opção: defina a sua variável a partir do objecto Jasper e depois basta chamar uma variável.
Operador de propagação: ES6
this.state = { jasper: { name: 'jasper', age: 28 } }
let foo = "something that needs to be saved into state"
this.setState(prevState => ({
jasper: {
...jasper.entity,
foo
}
})