Je vôbec možné aktualizovať vlastnosti objektu pomocou setState?
Niečo ako:
this.state = {
jasper: { name: 'jasper', age: 28 },
}
Skúšal som:
this.setState({jasper.name: 'someOtherName'});
a toto:
this.setState({jasper: {name: 'someothername'}})
Prvý spôsobí syntaktickú chybu a druhý nerobí nič. Nejaké nápady?
Existuje viacero spôsobov, ako to urobiť, pretože aktualizácia stavu je asynchrónna operácia, takže na aktualizáciu objektu stavu musíme použiť funkciu updater s funkciou setState
.
1- Najjednoduchší:
Najprv vytvorte kópiu jaspera
a potom v nej vykonajte zmeny:
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
})
Namiesto použitia Object.assign
to môžeme napísať aj takto:
let jasper = { ...prevState.jasper };
2- Použitie [spread operator]3:
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
}
}))
Poznámka: Object.assign
a Spread Operator
vytvárajú len plytkú kópiu, takže ak máte definovaný vnorený objekt alebo pole objektov, potrebujete iný prístup.
Predpokladajme, že ste definovali stav ako:
this.state = {
food: {
sandwich: {
capsicum: true,
crackers: true,
mayonnaise: true
},
pizza: {
jalapeno: true,
extraCheese: false
}
}
}
Aktualizácia extraCheese objektu 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
}
}
}))
Predpokladajme, že máte aplikáciu todo a spravujete údaje v tomto formulári:
this.state = {
todoItems: [
{
name: 'Learn React Basics',
status: 'pending'
}, {
name: 'Check Codebase',
status: 'pending'
}
]
}
Ak chcete aktualizovať stav ľubovoľného objektu todo, spustite mapu na poli a skontrolujte nejakú jedinečnú hodnotu každého objektu, v prípade condition=true
vráťte nový objekt s aktualizovanou hodnotou, inak ten istý objekt.
let key = 2;
this.setState(prevState => ({
todoItems: prevState.todoItems.map(
el => el.key === key? { ...el, status: 'done' }: el
)
}))
Návrh: Ak objekt nemá jedinečnú hodnotu, použite index poľa.
V prvom prípade ide skutočne o syntaktickú chybu.
Keďže nevidím zvyšok vášho komponentu, je ťažké zistiť, prečo tu vnášate objekty do svojho stavu. Nie je dobrý nápad vkladať objekty do stavu komponentu. Skúste nastaviť svoj počiatočný stav tak, aby bol:
this.state = {
name: 'jasper',
age: 28
}
Takto, ak chcete aktualizovať názov, môžete jednoducho zavolať:
this.setState({
name: 'Sean'
});
Dosiahnete tým to, o čo sa snažíte?
Pre väčšie a zložitejšie dátové úložiská by som použil niečo ako Redux. Ale to'je oveľa pokročilejšie.
Všeobecným pravidlom pri stave komponentov je používať ho len na správu stavu používateľského rozhrania komponentu (napr. aktívny, časovače atď.).
Pozrite si tieto odkazy:
Ďalšia možnosť: definujte svoju premennú z objektu Jasper a potom len zavolajte premennú.
Operátor rozšírenia: 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
}
})