Tüm geçişli erişilebilir durum dahil olmak üzere bir tepki bileşenini nasıl sıfırlayabilirim?


97

Zaman zaman, sıfırlamak istediğim kavramsal olarak durum bilgisi olan reaksiyon bileşenleri var. İdeal davranış, eski bileşeni kaldırmaya ve yeni, bozulmamış bir bileşeni okumaya eşdeğer olacaktır.

React setState, bileşenlerin kendi açık durumunu ayarlamaya izin veren, ancak tarayıcı odağı ve form durumu gibi örtük durumu hariç tutan ve ayrıca alt bileşenlerinin durumunu da hariç tutan bir yöntem sağlar. Tüm bu dolaylı durumu yakalamak zor bir görev olabilir ve her yeni şaşırtıcı durumla bir köstebek vurmak yerine bunu titizlikle ve tamamen çözmeyi tercih ederim.

Bunu yapmak için bir API veya model var mı?

Düzenleme:this.replaceState(this.getInitialState()) Yaklaşımı gösteren ve yaklaşımla karşılaştıran önemsiz bir örnek yaptım this.setState(this.getInitialState()): jsfiddle - replaceStatedaha sağlam.

Yanıtlar:


214

Bahsettiğiniz örtük tarayıcı durumunun ve çocuk durumunun sıfırlandığından emin olmak için, tarafından döndürülen kök düzeyi bileşene bir keyöznitelik ekleyebilirsiniz render; değiştiğinde, bu bileşen atılacak ve sıfırdan yaratılacaktır.

render: function() {
    // ...
    return <div key={uniqueId}>
        {children}
    </div>;
}

Bağımsız bileşenin yerel durumunu sıfırlamak için bir kısayol yoktur.


1
'Bileşen atılacak ve sıfırdan oluşturulacak' dediğinizde meraktan soruyorum, sanal DOM'un atılacağını ve sıfırdan oluşturulacağını, ancak DOM güncellemelerinin diff algoritmasına dayalı olarak yapılacağını mı söylüyorsunuz?
nimgrg

1
@nimgrg Hayır, gerçek DOM öğeleri de yeniden oluşturulacak. (Sanal DOM zaten her işlemede yeniden oluşturulmuştur, bu nedenle gerçek DOM'u korumak istiyorsanız key, bu durumda bir ayarlamayın .)
Sophie Alpert

3
@EamonNerbonne React 0.8'de, anahtarlar yalnızca bir dizideki kardeş öğeleri ayırt etmek için kullanılır ve kökte yok sayılır. Github.com/facebook/react/issues/590 adresine bakın .
Sophie Alpert

Not replaceState()ve getInitialState()her ikisi de yeni ES6 sınıf tarzı reactj'lerde kullanımdan kaldırılmıştır. this.setState(this._getInitialState())Bunun yerine kullanın . Ayrıca kendi durum başlatıcı işlevinizi isimlendiremezsiniz getInitialState()- react bir uyarı atar - başka bir şey çağırın ve açıkça state = this._getInitialState()sınıfın en üst seviyesinde yapın.
thom_nic

2
Bunu, dışarıdan bir anahtar desteği geçmesini gerektirmeden bir bileşenin içinden yapmanın bir yolu var mı?
trusktr

14

Aslında kaçınmalı replaceStateve setStatebunun yerine kullanmalısınız .

Belgeler replaceState"React'in gelecekteki bir sürümünde tamamen kaldırılabilir" diyor . Bence kesinlikle kaldırılacak çünkü replaceStateReact felsefesiyle pek uyuşmuyor. Bir React bileşeninin bir tür İsviçre bıçağı hissi vermeye başlamasını kolaylaştırır. Bu, bir React bileşeninin daha küçük ve daha amaca uygun hale gelmesinin doğal büyümesini engeller.

React'te, genelleme veya uzmanlaşma konusunda hata yapmanız gerekiyorsa: uzmanlaşmayı hedefleyin. Sonuç olarak, bileşeninizin devlet ağacının belirli bir cimri olması gerekir (yine de markalı yeni bir ürün geliştiriyorsanız, bu kuralı zevkli bir şekilde çiğnemek iyidir).

Her neyse, böyle yapıyorsun. Ben'in yukarıdaki (kabul edilmiş) cevabına benzer, ancak bunun gibi:

this.setState(this.getInitialState());

Ayrıca (Ben'in de söylediği gibi) "tarayıcı durumunu" sıfırlamak için bu DOM düğümünü kaldırmanız gerekir. Vdomun gücünden yararlanın ve keybu bileşen için yeni bir destek kullanın . Yeni render, bu bileşenin toptan yerini alacak.

Referans: https://facebook.github.io/react/docs/component-api.html#replacestate


2
Mevcut durum, başlangıç ​​durumunda olmayan herhangi bir özellik içeriyorsa bu işe yaramaz. Bunun içinde olmanın harika bir "durum" olduğuna inanmasam da, bir şekilde engelleyemezseniz, şaşırtıcı kırılmalardan kaçınmak isterim. Bir reset ile Tamam olacaktır çöküyor bazı durumlarda, ancak ustaca bozarsa devlet değil bir sıfırlama.
Eamon Nerbonne

Takip ettiğimden emin değilim. Bunun eşdeğer olmadığını this.replaceStatemı söylüyorsun ? Çünkü öyle.
wle8300

1
@ williamle8300 getInitialState()(örneğin, bir onClick işleyicisinde) çağrıları arasında bileşen yaşam döngüsünde bir yere yeni bir özellik eklenirse eşdeğer olmazlar . Bu durumda, söz konusu yeni mülk 2'den sonra da mevcut olacaktır getInitialState().
Graham

@Graham Daha önce beyan edilmemiş bir bileşene yeni durumu tanıtmanın kötü bir uygulama olduğuna inanıyorum getInitialState. Tüm değişkenlerinizi işlevin üst kısmındaki bir JS İşlevinde bildirmek gibi. Yan not: Ben Alpert'in çözümü benimkiyle neredeyse aynı ... ve o resmi bir React geliştiricisi!
wle8300

1
Korkarım getInitialState () fonksiyonu ve dolayısıyla cevap kullanımdan kaldırıldı. Bir güncelleme güzel olurdu.
Martin R.

10

keyÖğeye yeniden başlatmanız gereken bir öznitelik eklemek, öğe her değiştiğinde propsveya stateonunla ilişkilendirildiğinde onu yeniden yükleyecektir .

anahtar = {yeni Tarih (). getTime ()}

İşte bir örnek:

render() {
  const items = (this.props.resources) || [];
  const totalNumberOfItems = (this.props.resources.noOfItems) || 0;

  return (
    <div className="items-container">
      <PaginationContainer
        key={new Date().getTime()}
        totalNumberOfItems={totalNumberOfItems}
        items={items}
        onPageChange={this.onPageChange}
      />
    </div>
  );
}

1
Ya da anahtar olarak basit bir tamsayı sayacı değişkeni ekleyebilirsiniz
minimalist
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.