Bir React durumunu mutasyona uğratmanın tercih edilen yolu nedir?


97

Diyelim ki içimde bir this.state.listçocuk listesi oluşturmak için kullanabileceğim düz nesnelerin bir listesi var. O halde içine nesne eklemenin doğru yolu nedir this.state.list?

Aşağıda, işe yarayacağını düşündüğüm tek yol, çünkü this.statebelgede belirtildiği gibi doğrudan mutasyona uğrayamazsınız.

this._list.push(newObject):
this.setState({list: this._list});

Bu bana çirkin görünüyor. Daha iyi bir yol var mı?


ReactJS'deki durum dizilerinin doğru modifikasyonunun olası kopyası, birleştirme talep ediyor
Brigand

Tüm bu cevaplar, bir diziye bir eleman eklemekle ilgilidir. Peki ya ondan bir öğeyi kaldırmaya ne dersiniz? Veya diziyi tamamen yenisine sıfırlamak için mi?
Augustin Riedinger

Yanıtlar:


165

concat yeni bir dizi döndürür, böylece yapabilirsiniz

this.setState({list: this.state.list.concat([newObject])});

başka bir alternatif, React'in değişmezlik yardımcısıdır

  var newState = React.addons.update(this.state, {
      list : {
        $push : [newObject]
      }
  });

  this.setState(newState);

6
concatbir dizi alır, bu yüzden isteyeceksiniz this.state.list.concat([newObject]).
Sophie Alpert

@BenAlpert benim için Chrome'da çalışıyor, bunun standart dışı bir davranış olduğunu mu söylüyorsunuz?
Yığın

6
@Heap Pekala, eğer diziye olmayan concatbir diziyi bir diziye aktarırsanız , diziyi kendiniz eklemeniz daha iyidir: eğer bir sonraki elemanınız varsa [[1,2], [3,4]]ve eklemek istiyorsanız [5,6], .concat([[5,6]])başka bir şey yapmanız gerekir ile bitecek [[1,2], [3,4], 5, 6].
Sophie Alpert

2
Değişmezlik yardımcılarının arkasındaki fikri ne kadar takdir etsem de (ve yine de onu kullanmaya başlayabilirim), Array.concatbaşka bir kitaplık eklemekten daha iyi.
Shawn Erquhart

1
This.setState 'i this.state' den türetilen bir değerle çağırmak, güncelleme toplu işlem sorunlarıyla karşı karşıya kalmanıza neden olur. Karşılaşacağınız sorunu gösteren bir jsfiddle'a bağlanan stackoverflow.com/a/41445812/1998186 adresine bakın .
NealeU

40

setState () , parametre olarak bir işlevle çağrılabilir:

this.setState((state) => ({ list: state.list.concat(newObj) }))

veya ES5'te:

this.setState(function(state) {
  return {
   list: state.list.concat(newObj)
  }
})

2
@Arian: React, yalnızca yeni eklenen öğeleri oluşturmak için gerekli DOM mutasyon talimatlarını uygulayacaktır. Elbette yeni eklediğiniz öğeler, önceki öğelerin nasıl işlendiğini değiştirmez.
Jose Browne

1
Bu harika bir cevap ve sanırım öyle olsa da, sırf bir itme gerçekleştirmek için diziyi birleştirmekten çok daha temiz geliyor.
Matt Styles

2
@Nyalab, işlev gövdesini parantez içine almanız gerekmiyor mu? Şu anda örneğinizde olduğu gibi, şişman oktan sonraki parantezler bir nesneyi değil bir bloğu başlatır. Bunun gibi bir şey:this.setState((state) => ({ list: state.list.push(newObj) }))
kumarharsh

3
Bu kod nasıl çalışıyor? itme yöntemi NUMBER, listdeğişken üzerinde ayarlanacak olan a döndürür
kumarharsh

1
Ayrıca bir this.setState((state) => ({ list: [...state.list, newObj] }))
uyarı


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.