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.