Reac setState yöntemini çağırmak durumu derhal değiştirmez?


326

Formlar bölümünü okuyorumve sadece onChangekullanımı göstermek için bu kodu denedim ( JSBIN ).

var React= require('react');

var ControlledForm= React.createClass({
    getInitialState: function() {
        return {
            value: "initial value"
        };
    },

    handleChange: function(event) {
        console.log(this.state.value);
        this.setState({value: event.target.value});
        console.log(this.state.value);

    },

    render: function() {
        return (
            <input type="text" value={this.state.value} onChange={this.handleChange}/>
        );
    }
});

React.render(
    <ControlledForm/>,
  document.getElementById('mount')
);

Ben güncelleme yaparken <input/>tarayıcıda değerini, ikinci console.loghandleChangecallback'inde aynı yazdırır valueilk olarak console.logben sonucunu göremiyorum neden this.setState({value: event.target.value})kapsamındaki handleChangecallback'inde?


Yanıtlar:


615

React'in belgelerinden :

setState()hemen değişmez this.stateancak bekleyen bir durum geçişi oluşturur. this.stateBu yöntemi çağırdıktan sonra erişmek potansiyel olarak mevcut değeri döndürebilir. Çağrıların eşzamanlı çalışacağının garantisi yoktur setStateve performans kazanımları için çağrılar toplu olarak yapılabilir.

Durum değişikliği gerçekleştikten sonra bir işlevin yürütülmesini istiyorsanız, işlevi geri arama olarak iletin.

this.setState({value: event.target.value}, function () {
    console.log(this.state.value);
});

İyi cevap. Yapmam gereken gözlem valueLink'i kullanmaya dikkat etmek. Girişi biçimlendirmeniz / maskelemeniz gerekmiyorsa iyi çalışır.
Dherik

42
Ayrıca kontrol etmek isteyebilirsiniz componentDidUpdate. Devlet değiştikten sonra çağrılır.
Keysox

1
I-ebil hızlı soru, ben bir kez biz setState için geri arama olarak gereken işlevi geçmek görmek, ben render () çağrılmadan önce func ilk yürütüleceğini umuyordu. Ama görüyorum sipariş setState () -> render () -> setStates 'geri arama (). bu normal mi? Renderimizi geri aramada yaptığımız şeylere göre kontrol etmek istersek ne olur? BileşenUpdate mi?
semuzaboi

2
Bir bileşenin durumunun değiştirilmesi, shouldComponentUpdateaksi belirtilmedikçe , her zaman yeniden oluşturmayı tetikler . setStateYeniden oluşturma işleminden önce gerçekleşmesini istediğiniz geri aramada tam olarak ne yapmaya çalışıyorsunuz ?
Michael Parker

4
...neden? Birisi bunu haklı çıkarabilir mi?
JackHasaKeyboard

49

React belgelerinde belirtildiği gibi, setStateeşzamanlı olarak tetiklenmenin garantisi yoktur , bu nedenle console.loggüncellemeden önce durumu iade edebilirsiniz.

Michael Parker, içinde bir geri arama geçirmekten bahsediyor setState. Durum değişikliğinden sonra mantığı işlemenin başka bir yolu componentDidUpdate, React belgelerinde önerilen yöntem olan yaşam döngüsü yöntemidir.

Genellikle böyle bir mantık için componentDidUpdate () yöntemini kullanmanızı öneririz.

Bu özellikle art arda setStateişten çıkartıldığında yararlıdır ve her durum değişikliğinden sonra aynı işlevi başlatmak istediğinizde. Her birine bir geri arama eklemek setStateyerine, işlevi içine, componentDidUpdategerekirse belirli bir mantıkla yerleştirebilirsiniz.

// example
componentDidUpdate(prevProps, prevState) {
  if (this.state.value > prevState.value) {
    this.foo();  
  }
}

16

ES7 zaman uyumsuz / beklemesini kullanmayı deneyebilirsiniz. Örneğin, örneğinizi kullanarak:

handleChange: async function(event) {
    console.log(this.state.value);
    await this.setState({value: event.target.value});
    console.log(this.state.value);
}

Cevabınız diğer yüksek kaliteli cevaptan nasıl farklı?
tod

9
Diğer cevap, setState () öğesindeki geri aramanın kullanılmasıyla ilgilidir. Bunu geri arama kullanım durumu olmayanlar için buraya koyduğumu sanıyordum. Örneğin, bu sorunla kendim karşılaştığımda, kullanım durumum, ayarlandıktan hemen sonra güncellenmiş durumda bir anahtar durumu içeriyordu. Bu nedenle, geri çağırma yerine async / await kullanmak tercih edildi.
kurokiiru

Bir durumu güncellemek ve daha sonra güncellenmesini beklemek istediğimde her zaman beklersem bu performansı etkiler mi? Ve eğer birden fazla setStates'i birbirinin altında bir zincire koyarsam, her setState güncellemesinden sonra oluşturulur mı? veya son setState güncellemesinden sonra?
user2774480


User2774480'e ne soruyorsanız, hangi uygulamanın kullanılacağını belirlemek için her şeyin belirli bir kullanım durumuna geldiğine inanıyorum. Bir zincirde birden fazla setState kullanılırsa, performans etkilenir ve evet, her setState'ten sonra oluşturulur, ancak yanılıyorsam beni düzeltir.
kurokiiru


-1

async-await sözdizimi aşağıdaki gibi bir şey için mükemmel çalışır ...

changeStateFunction = () => {
  // Some Worker..

  this.setState((prevState) => ({
  year: funcHandleYear(),
  month: funcHandleMonth()
}));

goNextMonth = async () => {
  await this.changeStateFunction();
  const history = createBrowserHistory();
  history.push(`/calendar?year=${this.state.year}&month=${this.state.month}`);
}

goPrevMonth = async () => {
  await this.changeStateFunction();
  const history = createBrowserHistory();
  history.push(`/calendar?year=${this.state.year}&month=${this.state.month}`);
}

-1

Basitçe söylemek gerekirse - this.setState ({data: value}) doğası gereği zaman uyumsuzdur, yani Çağrı Yığını'ndan çıkar ve çözümlenmedikçe yalnızca Çağrı Yığını'na geri gelir.

JS'deki Eşzamansız doğa hakkında net bir resim ve güncellenmenin neden zaman aldığını öğrenmek için lütfen Etkinlik Döngüsü'nü okuyun -

https://medium.com/front-end-weekly/javascript-event-loop-explained-4cd26af121d4

Dolayısıyla -

    this.setState({data:value});
    console.log(this.state.data); // will give undefined or unupdated value

güncelleme zaman alır gibi. Yukarıdaki süreci gerçekleştirmek için -

    this.setState({data:value},function () {
     console.log(this.state.data);
    });
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.