React setState durumu güncellemiyor


91

Bu yüzden şuna sahibim:

let total = newDealersDeckTotal.reduce(function(a, b) {
  return a + b;
},
0);

console.log(total, 'tittal'); //outputs correct total
setTimeout(() => {
  this.setState({dealersOverallTotal: total});
}, 10);

console.log(this.state.dealersOverallTotal, 'dealersOverallTotal1'); //outputs incorrect total

newDealersDeckTotal sadece bir sayı dizisidir, [1, 5, 9]örneğin this.state.dealersOverallTotaldoğru toplamı vermez, ancak verir total? Bunun sorunu çözüp çözmediğini görmek için bir zaman aşımı gecikmesi bile koydum. açık mı yoksa daha fazla kod göndermeli miyim?



@Assan şerefe !!
Solucan

Cevaplarda söylenenlerin yanı sıra , aramadan önce devletin değerini açıkça kaydediyorsunuz setState.
Felix Kling

1
@FelixKling hayır bunu ayarladıktan sonra this.state'i arıyorum . Daha önce bir değişkeni günlüğe kaydediyorum. Hayır?
Solucan

Zaman aşımı nedeniyle setState, durumu günlüğe kaydettikten sonra gerçekten yürütülür. Sanırım hata ayıklamada yapmak istediğin, console.logparçayı zaman aşımının içine ve setStatedışına koymaktı.
Fabian Schultz

Yanıtlar:


182

setState()genellikle eşzamansızdır; bu, sizin console.logdurumunuz sırasında henüz güncellenmediği anlamına gelir . Günlüğü setState()yöntemin geri aramasına eklemeyi deneyin . Durum değişikliği tamamlandıktan sonra yürütülür:

this.setState({ dealersOverallTotal: total }, () => {
  console.log(this.state.dealersOverallTotal, 'dealersOverallTotal1');
}); 

1
Buna ek olarak, OP, aramadan önce durum değerini açıkça günlüğe kaydeder setState.
Felix Kling

Bu benim için de işe yarıyor, geçmişte bunu kullandım: `this.setState ({someVar: newValue}, function () {console.log (" force update}); 'ama nedense endişelenmiyordu Ben kodu güncellenen zaman o iş üstünde artık olarak tarif bir fikrin neden.?
Jozcar

@Jozcar sözdizimi sağ (parantez eksik) değil, aynı zamanda çalışması yapılmalıdır:this.setState({someVar: newValue},function(){ console.log("force update") });
Fabian Schultz

imgur.com/Ku0OjTl Lütfen bana bu sorundan kurtulmak için ne yapmam gerektiğini söyleyin.
Johncy

useStateİşlevsel bir bileşende kanca kullanırsanız bu işe yaramaz . useEffectBunun yerine, oluşturduktan sonra bir efekt için kullanın .
Hasan Sefa Özalp

16

setState zaman uyumsuzdur. Güncel durumu almak için geri arama yöntemini kullanabilirsiniz.

changeHandler(event) {
    this.setState({ yourName: event.target.value }, () => 
    console.log(this.state.yourName));
 }

10

Async / await kullanma

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

8

setState()Operasyondur asenkron ve dolayısıyla sizin console.log()önce çalıştırılacaktır setState()mutasyon değerleri ve dolayısıyla sen sonucunu görmek.

Bunu çözmek için setState(), aşağıdaki gibi geri arama işlevindeki değeri kaydedin :

setTimeout(() => {
    this.setState({dealersOverallTotal: total},
    function(){
       console.log(this.state.dealersOverallTotal, 'dealersOverallTotal1');
    });
}, 10)

JavaScript her zaman eşzamanlıdır.
Santosh Singh

1
@santoshsingh bir yanlış anlama var. API çağrıları, zaman aşımlarının tümü eşzamansız olarak gerçekleşir.
Shubham Khatri

Yukarıda belirttiğiniz gibi javascript eşzamansızdır - bu doğru değil. Çoğunlukla eşzamanlıdır ve durumlar için eşzamansızdır. stackoverflow.com/questions/2035645/…
Santosh Singh

@santoshsingh. Ohh bu benim açımdan bir hataydı. Cümleyi doğru oluşturmadı
Shubham Khatri

sonraki aramadan önce durumun güncellenmesini sağlamak için geri aramanın çok akıllıca kullanılması!
user1204214

5

useEffectKanca olması durumunda kanca kullanmalısınız .

const [fruit, setFruit] = useState('');

setFruit('Apple');

useEffect(() => {
  console.log('Fruit', fruit);
}, [fruit])

Harika, useEffect ile çalışıyor. Ama neden ihtiyaç duyuyor?
alex351

useEffecther yeniden oluşturmada çalışır ve diziye iletilen öğeler durum değişkeni ise sand değiştirilir. Dolayısıyla, meyve değiştiğinde ve bileşen yeniden oluşturulduğunda, bu useEffect çalışacaktır.
Siraj Alam

SetFruit ve console.log meyvelerini useEffect dışında çalıştırıyorum ve değişmiyor. : /
alex351

3

Setstate react'te asenkrondur, bu nedenle konsolda güncellenmiş durumu görmek için aşağıda gösterildiği gibi geri aramayı kullanın (Geri arama işlevi setstate güncellemesinden sonra çalıştırılır)

görüntü açıklamasını buraya girin

Aşağıdaki yöntem "önerilmez", ancak anlamak için, durumu doğrudan değiştirirseniz, bir sonraki satırda güncellenmiş durumu görebilirsiniz. Tekrar ediyorum, bunun "önerilmez"

görüntü açıklamasını buraya girin


TEŞEKKÜRLER işte bu, değişkeni doğrudan ayarlamalısın
notacorn


0

Birden çok kez tepki durumunu ayarlarken bir sorun yaşadım (her zaman varsayılan durumu kullandı). Bu react / github sorununu takiben benim için çalıştı

const [state, setState] = useState({
  foo: "abc",
  bar: 123
});

// Do this!
setState(prevState => {
  return {
    ...prevState,
    foo: "def"
  };
});
setState(prevState => {
  return {
    ...prevState,
    bar: 456
  };
});

0

Bazı karmaşık kodlarla aynı duruma sahiptim ve mevcut önerilerden hiçbir şey benim için işe yaramadı.

Benim sorunum, setStatebileşenlerden biri tarafından verilen geri arama işlevinden kaynaklanıyordu. Ve şüphem, aramanın eşzamanlı olarak gerçekleşmesi ve bu da setStatedurumun ayarlanmasını tamamen engellemesi .

Basitçe şöyle bir şeye sahibim:

render() {
    <Control
        ref={_ => this.control = _}
        onChange={this.handleChange}
        onUpdated={this.handleUpdate} />
}

handleChange() {
    this.control.doUpdate();
}

handleUpdate() {
    this.setState({...});
}

Ben "düzeltme" zorunda yolu koymak oldu doUpdate()içine setTimeoutböyle:

handleChange() {
    setTimeout(() => { this.control.doUpdate(); }, 10);
}

İdeal değil, ancak aksi takdirde önemli bir yeniden düzenleme olur.

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.