Kapan menggunakan React setState callback

191

Ketika keadaan komponen reaksi berubah, metode render disebut. Karenanya untuk setiap perubahan keadaan, tindakan dapat dilakukan dalam badan metode render. Apakah ada use case khusus untuk callback setState?

Sahil Jain
sumber
4
Saat ini tidak jelas apa yang Anda minta. Bisakah Anda memasukkan beberapa kode?
Davin Tryon
2
Callback setState adalah untuk apa pun yang ingin Anda lakukan setelah keadaan PASTI berubah. Karena setState adalah async, jika Anda ingin memanggil fx dan yakin bahwa keadaan baru tersebut dimuat maka itulah
gunanya
3
Kasus penggunaan untuk callback setState cukup jelas. Anda menggunakannya ketika Anda ingin fungsi untuk dijalankan setelah negara SPECIFICIC diperbarui. Jika Anda memasukkan fungsi ini render()sebagai gantinya, itu akan berjalan setiap kali keadaan APA PUN diperbarui, yang mungkin bukan yang Anda inginkan. Ini juga akan membuat kode Anda kurang mudah dibaca dan logis.
M3RS

Jawaban:

225

Ya ada, karena setStatebekerja dengan asynchronouscara tertentu. Itu berarti setelah memanggil setStateyang this.statevariabel tidak segera berubah. jadi jika Anda ingin melakukan tindakan segera setelah menetapkan status pada variabel keadaan dan kemudian mengembalikan hasilnya, panggilan balik akan berguna

Perhatikan contoh di bawah ini

....
changeTitle: function changeTitle (event) {
  this.setState({ title: event.target.value });
  this.validateTitle();
},
validateTitle: function validateTitle () {
  if (this.state.title.length === 0) {
    this.setState({ titleError: "Title can't be blank" });
  }
},
....

Kode di atas mungkin tidak berfungsi seperti yang diharapkan karena titlevariabel mungkin tidak bermutasi sebelum validasi dilakukan di atasnya. Sekarang Anda mungkin bertanya-tanya bahwa kita dapat melakukan validasi dalam render()fungsi itu sendiri tetapi akan lebih baik dan lebih bersih jika kita dapat menangani ini dalam fungsi changeTitle sendiri karena itu akan membuat kode Anda lebih terorganisir dan dapat dipahami

Dalam hal ini panggilan balik berguna

....
changeTitle: function changeTitle (event) {
  this.setState({ title: event.target.value }, function() {
    this.validateTitle();
  });

},
validateTitle: function validateTitle () {
  if (this.state.title.length === 0) {
    this.setState({ titleError: "Title can't be blank" });
  }
},
....

Contoh lain adalah ketika Anda ingin dispatchdan bertindak ketika negara berubah. Anda akan ingin melakukannya dalam panggilan balik dan bukan render()seperti yang akan disebut setiap kali rerendering terjadi dan karenanya banyak skenario seperti itu mungkin terjadi di mana Anda akan membutuhkan panggilan balik.

Kasus lain adalah a API Call

Suatu kasus dapat muncul ketika Anda perlu melakukan panggilan API berdasarkan perubahan status tertentu, jika Anda melakukannya dalam metode render, itu akan dipanggil pada setiap onStateperubahan render atau karena beberapa Prop diturunkan ke Child Componentperubahan.

Dalam hal ini Anda ingin menggunakan a setState callbackuntuk meneruskan nilai status yang diperbarui ke panggilan API

....
changeTitle: function (event) {
  this.setState({ title: event.target.value }, () => this.APICallFunction());
},
APICallFunction: function () {
  // Call API with the updated value
}
....
Shubham Khatri
sumber
3
Saya mengerti bahwa itu asinkron. Pertanyaan saya adalah adakah sesuatu yang spesifik yang hanya callback setState yang dapat digunakan untuk itu yang mungkin tidak didukung oleh badan metode render (Sesuatu yang terpisah dari katakanlah pembacaan kode yang lebih baik.)
Sahil Jain
@SahilJain Validation adalah contoh yang benar, Anda tidak ingin menanganinya dalam fungsi render () karena dengan itu akan dipanggil setiap kali Anda membuat perubahan dalam render () Anda ingin memanggilnya hanya ketika hanya input yang berubah dan karenanya dalam fungsi itu sendiri
Shubham Khatri
Bereaksi melarang untuk mengubah negara selama render .. Jadi haknya untuk memasukkan validasi ke dalam callback.
webdeb
if (this.title.length === 0) {seharusnya this.state.title.length, kan?
Dmitry Minkovsky
4
Kasus penggunaan pertama mungkin bukan ide yang baik. setState callback trigger setelah re-render, jadi Anda menyebabkan render ganda tanpa alasan yang jelas. Ini persis tujuan dari argumen fungsi (pembaru). Anda bisa menjalankan setState(state => state.title.length ? { titleError: "Title can't be blank" } : null)dan perubahan akan menumpuk. Tidak perlu render ganda.
R Esmond
47
this.setState({
    name:'value' 
},() => {
    console.log(this.state.name);
});
Araz Babayev
sumber
14
Terima kasih atas cuplikan kode ini, yang mungkin memberikan bantuan terbatas dan segera. Sebuah penjelasan yang tepat akan sangat meningkatkan nilai jangka panjang dengan menunjukkan mengapa ini adalah solusi yang baik untuk masalah ini, dan akan membuatnya lebih bermanfaat untuk pembaca masa depan dengan lainnya, pertanyaan-pertanyaan serupa. Harap edit jawaban Anda untuk menambahkan beberapa penjelasan, termasuk asumsi yang Anda buat.
Machavity
1
Saat Anda ingin memanggil fungsi setelah keadaan berubah, Anda dapat menggunakan metode ini.
Araz Babayev
bagaimana jika Anda ingin mengatur beberapa properti negara seperti nama, nama depan dll?
Sumanth Varada
44

1. usecase yang muncul di benak saya, adalah apipanggilan, yang seharusnya tidak masuk ke render, karena akan berjalan untuk eachperubahan keadaan. Dan panggilan API harus dilakukan hanya pada perubahan status khusus, dan tidak pada setiap render.

changeSearchParams = (params) => {
  this.setState({ params }, this.performSearch)
} 

performSearch = () => {
  API.search(this.state.params, (result) => {
    this.setState({ result })
  });
}

Karenanya untuk setiap perubahan keadaan, tindakan dapat dilakukan dalam badan metode render.

Praktek yang sangat buruk , karena render-metode harus murni, itu berarti tidak ada tindakan, perubahan negara, panggilan api, harus dilakukan, hanya komposit pandangan Anda dan kembalikan. Tindakan harus dilakukan pada beberapa acara saja. Render bukan acara, tapi componentDidMountmisalnya.

webdeb
sumber
25

Pertimbangkan panggilan setState

this.setState({ counter: this.state.counter + 1 })

IDE

setState dapat dipanggil dalam fungsi async

Jadi Anda tidak bisa mengandalkan this. Jika panggilan di atas dilakukan di dalam fungsi async thisakan merujuk ke status komponen pada titik waktu tersebut, tetapi kami berharap ini merujuk ke properti di dalam status pada saat setState memanggil atau memulai tugas async. Dan sebagai tugas adalah panggilan async sehingga properti itu mungkin telah berubah pada waktunya. Oleh karena itu tidak dapat diandalkan untuk menggunakan thiskata kunci untuk merujuk ke beberapa properti negara sehingga kami menggunakan fungsi callback yang argumennya adalahState sebelumnya dan alat peraga yang berarti ketika tugas async dilakukan dan sudah waktunya untuk memperbarui keadaan menggunakan panggilan setState prevState akan merujuk ke status sekarang ketika setState belum dimulai. Memastikan keandalan bahwa nextState tidak akan rusak.

Kode yang salah: akan menyebabkan korupsi data

this.setState(
   {counter:this.state.counter+1}
 );

Kode yang benar dengan setState memiliki fungsi panggilan balik:

 this.setState(
       (prevState,props)=>{
           return {counter:prevState.counter+1};
        }
    );

Jadi setiap kali kita perlu memperbarui keadaan kita saat ini ke keadaan berikutnya berdasarkan nilai yang dimiliki oleh properti sekarang dan semua ini terjadi dalam mode async, adalah ide yang baik untuk menggunakan setState sebagai fungsi panggilan balik.

Saya telah mencoba menjelaskannya dalam codepen di sini KODE PENA

Aniket Jha
sumber