Nesnenin özelliklerini setState ile güncellemek mümkün müdür?
Şöyle bir şey:
this.state = {
jasper: { name: 'jasper', age: 28 },
}
Denedim:
this.setState({jasper.name: 'someOtherName'});
ve bu:
this.setState({jasper: {name: 'someothername'}})
İlki bir sözdizimi hatasıyla sonuçlanırken ikincisi hiçbir şey yapmaz. Fikri olan var mı?
Durum güncellemesi bir async işlemi olduğundan, bunu yapmanın birden fazla yolu vardır, bu nedenle durum nesnesini güncellemek için setState
ile updater işlevi kullanmamız gerekir.
1- En basit olanı:
Önce jasper
ın bir kopyasını oluşturun, ardından değişiklikleri bu kopyada yapın:
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
})
Object.assign` kullanmak yerine bu şekilde de yazabiliriz:
let jasper = { ...prevState.jasper };
2- [yayma operatörünü]3 kullanma:
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
}
}))
Not: Object.assign
ve Spread Operator
yalnızca shallow copy oluşturur, bu nedenle iç içe nesne veya nesne dizisi tanımladıysanız, farklı bir yaklaşıma ihtiyacınız vardır.
Durumu şu şekilde tanımladığınızı varsayalım:
this.state = {
food: {
sandwich: {
capsicum: true,
crackers: true,
mayonnaise: true
},
pizza: {
jalapeno: true,
extraCheese: false
}
}
}
Pizza nesnesinin extraCheese öğesini güncellemek için:
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
}
}
}))
Bir yapılacaklar uygulamanız olduğunu ve bu formdaki verileri yönettiğinizi varsayalım:
this.state = {
todoItems: [
{
name: 'Learn React Basics',
status: 'pending'
}, {
name: 'Check Codebase',
status: 'pending'
}
]
}
Herhangi bir todo nesnesinin durumunu güncellemek için, dizi üzerinde bir harita çalıştırın ve her nesnenin bazı benzersiz değerlerini kontrol edin, condition=true
durumunda, güncellenmiş değere sahip yeni nesneyi döndürün, aksi takdirde aynı nesneyi döndürün.
let key = 2;
this.setState(prevState => ({
todoItems: prevState.todoItems.map(
el => el.key === key? { ...el, status: 'done' }: el
)
}))
Öneri: Nesnenin benzersiz bir değeri yoksa, dizi indeksi kullanın.
İlk durum gerçekten de bir sözdizimi hatasıdır.
Bileşeninizin geri kalanını göremediğim için, burada durumunuzdaki nesneleri neden iç içe yerleştirdiğinizi görmek zor. Bileşen durumundaki nesneleri iç içe yerleştirmek iyi bir fikir değildir. Başlangıç durumunuzu şu şekilde ayarlamayı deneyin:
this.state = {
name: 'jasper',
age: 28
}
Bu şekilde, adı güncellemek isterseniz, sadece arayabilirsiniz:
this.setState({
name: 'Sean'
});
Bu, hedeflediğiniz şeye ulaşmanızı sağlayacak mı?
Daha büyük, daha karmaşık veri depoları için Redux gibi bir şey kullanırdım. Ama bu çok daha gelişmiş bir yöntem.
Bileşen durumu ile ilgili genel kural, bunu yalnızca bileşenin kullanıcı arayüzü durumunu yönetmek için kullanmaktır (örn. etkin, zamanlayıcılar, vb.)
Bu referanslara göz atın:
Başka bir seçenek: değişkeninizi Jasper nesnesi dışında tanımlayın ve sonra sadece bir değişkeni çağırın.
Yayılma operatörü: 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
}
})