This.setState'i React bileşeninde birden çok kez kullandığınızda ne olur?


105

This.setState'i birden çok kez kullandığınızda ne olacağını kontrol etmek istedim (tartışma uğruna 2 kez). Bileşenin iki kez işleneceğini düşünmüştüm ama görünüşe göre sadece bir kez işleniyor. Bir başka beklentim de, setState için ikinci çağrının birincisinin üzerinden geçeceğiydi, ama siz tahmin ettiniz - iyi çalıştı.

Bir bağlantı JSfiddle

var Hello = React.createClass({
  render: function() {
    return (
      <div>
        <div>Hello {this.props.name}</div>
        <CheckBox />
      </div>
    );
  }
});

var CheckBox = React.createClass({
  getInitialState: function() {
    return {
      alex: 0
    };
  },

  handleChange: function(event) {
    this.setState({
      value: event.target.value
    });
    this.setState({
      alex: 5
    });
  },

  render: function() {
    alert('render');
    return (
      <div>
        <label htmlFor="alex">Alex</label>
        <input type="checkbox" onChange={this.handleChange} name="alex" />
        <div>{this.state.alex}</div>
      </div>
    );
  }
});

ReactDOM.render(
  <Hello name="World" />,
  document.getElementById('container')
);

Göreceğiniz gibi, her işlemede 'render' yazan bir uyarı belirir.

Neden düzgün çalıştığına dair bir açıklamanız var mı?


2
React oldukça zekidir ve yalnızca render etmek için gereken durum değiştiğinde yeniden oluşturulur. Oluşturma yönteminizde yalnızca kullanıyorsunuz this.state.alex- buna bağlı olan bir öğe de eklerseniz ne olur this.state.value?
Martin Wedvich

1
@MartinWedvich Bağımlı olmam durumunda kırılır. Bunun için, uygulamanızın bozulmaması için varsayılan değerleri ayarlamak için 'getInitialState' yöntemine sahipsiniz.
alexunder

Yanıtlar:


120

React toplu işlemleri, olay işleyicilerinde ve yaşam döngüsü yöntemlerinde meydana gelen güncellemelerin durumunu belirtir. Bu nedenle, durumu bir <div onClick />işleyicide birden çok kez güncellerseniz , React yeniden işlemeden önce olay işlemenin bitmesini bekler.

Açık olmak gerekirse, bu yalnızca React kontrollü sentetik olay işleyicilerinde ve yaşam döngüsü yöntemlerinde çalışır. Durum güncellemeleri, setTimeoutörneğin AJAX ve olay işleyicilerinde toplu olarak işlenmez .


1
Teşekkürler, mantıklı, perde arkasında nasıl yapıldığına dair bir fikriniz var mı?
alexunder

15
React, sentetik olay işleyicileri (gibi <div onClick />) ve bileşen yaşam döngüsü yöntemlerini tam olarak kontrol ettiğinden, setStatetoplu durum güncellemelerine çağrı süresi boyunca davranışını güvenli bir şekilde değiştirebileceğini ve temizlemeyi bekleyebileceğini bilir . Bunun setTimeoutaksine bir AJAX veya işleyicide, React'in işleyicimizin uygulamayı ne zaman bitirdiğini bilmesinin bir yolu yoktur. Teknik olarak, React kuyrukları her iki durumda da güncellemeleri belirtir, ancak React kontrollü bir işleyicinin hemen dışında temizler.
Chris Gaudreau

2
@neurosnap Dokümanların bu konuda fazla ayrıntıya girdiğini sanmıyorum. State and Lifecycle bölümünde ve setState belgelerinde soyut olarak bahsedilmektedir . Şu anda tek resmi gruplama stratejisi olan ReactDefaultBatchingStrategy koduna bakın .
Chris Gaudreau

2
@BenjaminToueg React olay işleyicileri dışında ReactDOM.unstable_batchedUpdates(function)toplu işlem yapabileceğinize inanıyorum setState. Adından da anlaşılacağı gibi garantinizi geçersiz kılacaksınız.
Chris Gaudreau

1
bu adama
atıfta bulunmak

37

SetState () yöntemi bileşenin durumunu hemen güncellemez, sadece güncellemeyi daha sonra işlenmek üzere bir kuyruğa koyar. React, oluşturmayı daha verimli hale getirmek için birden çok güncelleme isteğini bir araya getirebilir. Bu nedenle, durumu bileşenin önceki durumuna göre güncellemeye çalıştığınızda özel önlemler alınmalıdır.

Örneğin, aşağıdaki kod, 4 kez çağrılmasına rağmen durum değeri özniteliğini yalnızca 1 artıracaktır:

 class Counter extends React.Component{
   constructor(props){
     super(props)
    //initial state set up
     this.state = {value:0}
   }
   componentDidMount(){
    //updating state
    this.setState({value:this.state.value+1})
    this.setState({value:this.state.value+1})
    this.setState({value:this.state.value+1})
    this.setState({value:this.state.value+1})
   }
   render(){
    return <div>Message:{this.state.value}</div>
   }
}

Bir durumu güncellendikten sonra kullanmak için geri arama bağımsız değişkenindeki tüm mantığı yapın:

//this.state.count is originally 0
this.setState({count:42}, () => {
  console.log(this.state.count)
//outputs 42
})

SetState (güncelleyici, [geri arama]) yöntemi, durumu önceki duruma ve özelliklere göre güncellemek için ilk argüman olarak bir güncelleyici işlevini alabilir. Güncelleyici işlevinin dönüş değeri, önceki bileşen durumuyla yüzeysel olarak birleştirilecektir. Yöntem, durumu eşzamansız olarak günceller, bu nedenle, durum tamamen güncellemeyi bitirdiğinde çağrılacak bir seçenek geri çağrısı vardır.

Misal:

this.setState((prevState, props) => { 
return {attribute:"value"}
})

Durumun önceki duruma göre nasıl güncelleneceğine dair bir örnek:

    class Counter extends React.Component{
      constructor(props) {
        super(props)
    //initial state set up
        this.state = {message:"initial message"}
    }
      componentDidMount() {
    //updating state
        this.setState((prevState, props) => {
          return {message: prevState.message + '!'}
        })
     }
     render(){
       return <div>Message:{this.state.message}</div>
     }
  }

Ah, bilmiyordum setState(updater,[callback]), bunun için daha az ayrıntılı bir Object.assignteşekkür gibi !
AJ Venturella

2
@Biboswan, merhaba, React'te yeniyim ve size sormak istiyorum, CompountDidMount yöntemindeki dört setState'in de birleştirildiği ve SADECE SON setState'in çalıştırılacağı ancak diğer 3'ün göz ardı edileceği doğru mu?
Dickens
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.