React.useState tidak memuat ulang status dari props

95

Saya mengharapkan status untuk memuat ulang pada perubahan alat peraga, tetapi ini tidak berfungsi dan uservariabel tidak diperbarui pada useStatepanggilan berikutnya , apa yang salah?

function Avatar(props) {
  const [user, setUser] = React.useState({...props.user});
  return user.avatar ? 
         (<img src={user.avatar}/>)
        : (<p>Loading...</p>);
}

codepen

vitalyster
sumber

Jawaban:

211

Argumen yang diteruskan ke useState adalah keadaan awal seperti keadaan pengaturan dalam konstruktor untuk komponen kelas dan tidak digunakan untuk memperbarui keadaan saat render ulang

Jika Anda ingin memperbarui status pada perubahan prop, gunakan useEffecthook

function Avatar(props) {
  const [user, setUser] = React.useState({...props.user});

  React.useEffect(() => {
      setUser(props.user);
  }, [props.user])

  return user.avatar ? 
         (<img src={user.avatar}/>)
        : (<p>Loading...</p>);
}

Demo kerja

Shubham Khatri
sumber
18
Ketika mengatur keadaan awal dalam konstruktor, jelas untuk memahami bahwa konstruktor dipanggil sekali pada pembuatan instance kelas. Dengan hook, sepertinya useState dipanggil setiap kali saat pemanggilan fungsi dan setiap kali harus menginisialisasi status, tetapi beberapa "keajaiban" yang tidak dapat dijelaskan terjadi di sana.
vitalyster
Mungkin posting ini menjelaskannya stackoverflow.com/questions/54673188/…
Shubham Khatri
jika Anda perlu menggabungkan props ke dalam status, Anda akan terjebak dalam loop tak terbatas saat menggunakan create-react-app yang mengharuskan status berada dalam larik ketergantungan
user210757
2
Ini akhirnya mengatur keadaan awal dua kali yang cukup mengganggu. Saya ingin tahu apakah Anda dapat mengatur status awal ke null dan kemudian menggunakan React.useEffectuntuk mengatur status awal setiap saat.
CMCDragonkai
2
Ini tidak berfungsi jika negara juga mengontrol rendering. Saya memiliki komponen fungsional yang membuat berdasarkan alat peraga dan membuat berdasarkan keadaan. Jika status memberi tahu komponen untuk dirender karena diubah, maka useEffect akan berjalan dan menyetel status kembali ke nilai default. Ini adalah desain yang sangat buruk di pihak mereka.
Greg Veres
1

Komponen fungsional yang kita gunakan useStateuntuk mengatur nilai awal ke variabel kita, jika kita melewatkan nilai awal melalui props, itu akan selalu menetapkan nilai awal yang sama sampai Anda tidak menggunakan useEffecthook,

misalnya kasus Anda ini akan melakukan pekerjaan Anda

 React.useEffect(() => {
      setUser(props.user);
  }, [props.user])

Fungsi yang diteruskan ke useEffect akan berjalan setelah render diterapkan ke layar.

Secara default, efek dijalankan setelah setiap render selesai, tetapi Anda dapat memilih untuk mengaktifkannya hanya jika nilai tertentu telah berubah.

React.useEffect(FunctionYouWantToRunAfterEveryRender)

jika Anda hanya mengirimkan satu argumen ke useEffect, metode ini akan menjalankan metode ini setelah setiap render Anda dapat memutuskan kapan harus mengaktifkannya FunctionYouWantToRunAfterEveryRenderdengan meneruskan argumen kedua ke useEffect

React.useEffect(FunctionYouWantToRunAfterEveryRender, [props.user])

seperti yang Anda perhatikan, saya sedang melewati [props.user] sekarang useEffecthanya akan mengaktifkan FunctionYouWantToRunAfterEveryRenderfungsi ini jika props.userdiubah

Saya harap ini membantu pemahaman Anda, beri tahu saya jika ada perbaikan yang diperlukan, terima kasih

Hanzla Habib
sumber
0

Parameter yang diteruskan ke React.useState()hanya nilai awal untuk status tersebut. React tidak akan mengenali itu sebagai mengubah keadaan, hanya mengatur nilai defaultnya. Anda akan ingin menyetel status default pada awalnya, lalu memanggil secara bersyarat setUser(newValue), yang akan dikenali sebagai status baru, dan merender ulang komponen.

Saya akan merekomendasikan dengan hati-hati memperbarui status tanpa beberapa jenis kondisi untuk menjaganya dari terus-menerus memperbarui, dan karena itu rendering ulang setiap alat peraga diterima. Anda mungkin ingin mempertimbangkan untuk mengangkat fungsionalitas status ke komponen induk dan meneruskan status induk ke Avatar ini sebagai penyangga.

Mengantuk
sumber
-2

Menurut dokumentasi ReactJS tentang Hooks :

Tetapi apa yang terjadi jika teman prop berubah saat komponen ada di layar? Komponen kami akan terus menampilkan status online teman yang berbeda. Ini adalah bug. Kami juga akan menyebabkan kebocoran memori atau crash saat melepas karena panggilan berhenti berlangganan akan menggunakan ID teman yang salah.

Satu-satunya interaksi Anda di sini harus terjadi pada perubahan alat peraga, yang tampaknya tidak berhasil. Anda dapat (masih menurut dokumen) menggunakan componentDidUpdate (prevProps) untuk secara proaktif menangkap pembaruan apa pun ke props.

PS: Saya tidak memiliki cukup kode untuk menilai, tetapi tidak bisakah Anda secara aktif mengaturUser () di dalam fungsi Avatar (props) Anda?

Mwak
sumber
-12

Di dunia react, Anda harus memperbarui status Anda dalam fungsi componentWillRecieveProps (nextProps), dalam kasus seperti itu.

Sushil Mahajan
sumber
4
Yang tidak berlaku lagi untuk versi terbaru dari react
Shubham Khatri