Rumah > hujung hadapan web > tutorial css > React Suspense: Pelajaran yang dipelajari semasa memuatkan data

React Suspense: Pelajaran yang dipelajari semasa memuatkan data

尊渡假赌尊渡假赌尊渡假赌
Lepaskan: 2025-03-18 10:18:15
asal
985 orang telah melayarinya

React Suspense: Pelajaran yang dipelajari dari pemuatan data

React Suspense: Pelajaran yang dipelajari semasa memuatkan data

Ketegangan adalah ciri yang akan datang dari React yang membantu menyelaraskan operasi asynchronous seperti pemuatan data, menjadikannya mudah bagi anda untuk mengelakkan ketidakkonsistenan negara dalam UI. Saya akan menerangkan dengan lebih terperinci apa maksudnya, dan memberikan pengenalan ringkas kepada ketegangan, maka kes penggunaan yang lebih realistik dan beberapa pelajaran yang dipelajari.

Fungsi yang saya diperkenalkan masih dalam peringkat alfa dan tidak boleh digunakan dalam persekitaran pengeluaran. Siaran ini adalah untuk mereka yang ingin melihat ciri -ciri pertama yang akan datang dan memahami di mana mereka akan menuju ke masa depan.

Bermula dengan ketegangan

Salah satu bahagian pembangunan aplikasi yang paling mencabar ialah menyelaraskan keadaan aplikasi dan bagaimana data dimuatkan. Perubahan negeri biasanya mencetuskan pemuatan data baru di pelbagai lokasi. Biasanya, setiap sekeping data akan mempunyai UI pemuatan sendiri (seperti "pemutar") yang kira -kira di mana data berada dalam aplikasi. Sifat pemuatan data yang tidak segerak bermakna bahawa permintaan ini dapat dikembalikan dalam apa -apa perintah. Akibatnya, bukan sahaja permohonan anda akan muncul dan hilang dengan banyak pemintal yang berbeza, tetapi lebih buruk lagi, aplikasi anda mungkin memaparkan data yang tidak konsisten. Sekiranya dua daripada tiga beban data anda selesai, anda akan melihat pemutar beban di bahagian atas kedudukan ketiga, masih menunjukkan data lama yang sudah lama sudah lama.

Saya tahu itu terlalu banyak. Sekiranya anda mendapati mana -mana mengelirukan, anda mungkin berminat dengan artikel sebelumnya mengenai ketegangan yang saya tulis. Artikel ini memperkenalkan lebih terperinci apa ketegangan dan apa yang dilaksanakannya. Perhatikan bahawa beberapa butiran kecil ini kini sudah lapuk, iaitu cangkuk useTransition tidak lagi menerima nilai timeoutMs , tetapi menunggu selama -lamanya.

Sekarang, mari kita lihat dengan cepat butiran dan kemudian teruskan ke kes penggunaan tertentu dengan beberapa perangkap yang mengintai.

Bagaimana ketegangan berfungsi

Nasib baik, pasukan React cukup pintar untuk tidak mengehadkan usaha ini untuk hanya memuatkan data. Ketegangan berfungsi melalui primitif peringkat rendah, yang boleh anda gunakan untuk hampir apa-apa. Mari kita lihat dengan cepat pada primitif ini.

Pertama sekali<suspense></suspense> Sempadan, ia menerima atribut fallback :

<suspense fallback="{<Fallback"></suspense> }>
Salin selepas log masuk
Salin selepas log masuk

Setiap kali mana -mana komponen kanak -kanak di bawah komponen ini digantung, ia menjadikan fallback . Tidak kira berapa banyak subkomponen digantung, atas sebab apa pun, fallback dipaparkan. Ini adalah satu cara yang bertindak balas memastikan bahawa UI adalah konsisten - ia tidak akan menyebabkan apa -apa sehingga semuanya siap.

Tetapi apa yang berlaku apabila pengguna mengubah status dan memuat data baru selepas kandungannya pada mulanya diberikan? Kami pastinya tidak mahu UI kami yang sedia ada hilang dan menunjukkan fallback kami; itu akan menjadi pengalaman pengguna yang buruk. Sebaliknya, kami mungkin mahu memaparkan pemutar pemuatan sehingga semua data siap sebelum UI baru dipaparkan.

Hook useTransition melaksanakan ini. Cangkuk ini mengembalikan fungsi dan nilai boolean. Kami memanggil fungsi dan membungkus perubahan keadaan kita. Sekarang perkara semakin menarik. React cuba menerapkan perubahan status kami. Jika ada yang tergantung, React menetapkan nilai boolean kepada true dan menunggu hang ke akhir. Setelah selesai, ia akan cuba menggunakan perubahan status lagi. Mungkin ia akan berjaya kali ini, atau mungkin sesuatu yang lain akan digantung. Bagaimanapun, bendera Boolean akan tetap true sehingga semuanya siap, dan hanya kemudian perubahan keadaan akan diselesaikan dan dicerminkan dalam UI.

Akhirnya, bagaimana kita menggantung? Kami menggantung dengan melemparkan janji. Jika data diminta dan kita perlu mengambil, maka kita mengambil - dan membuang janji yang berkaitan dengan pengambilan itu. Mekanisme penggantungan peringkat rendah ini bermakna kita boleh menggunakannya untuk apa-apa. Utiliti React.lazy untuk komponen pemuatan malas sudah berfungsi dengan ketegangan, dan saya telah menulis sebelum menggunakan ketegangan untuk menunggu imej dimuatkan sebelum memaparkan UI untuk mengelakkan kandungan bergerak.

Jangan risau, kami akan membincangkan semua ini.

Apa yang kita bina

Kami akan membina sesuatu yang sedikit berbeza dari contoh -contoh dalam artikel lain yang serupa. Ingat bahawa ketegangan masih dalam fasa alfa, jadi utiliti data pemuatan kegemaran anda mungkin tidak mempunyai sokongan ketegangan lagi. Tetapi itu tidak bermakna kita tidak boleh menipu sesuatu dan memahami bagaimana ketegangan berfungsi.

Mari kita bina senarai pemuatan tak terhingga yang memaparkan beberapa data dan menggabungkan beberapa imej yang dimuatkan berdasarkan ketegangan. Kami akan memaparkan data kami, serta butang untuk memuat lebih banyak data. Apabila data diberikan, kami akan memuatkan imej yang berkaitan dan menggantung sebelum ia siap.

Kes penggunaan ini berdasarkan kerja sebenar yang saya lakukan di projek sampingan saya (sekali lagi, jangan gunakan ketegangan dalam pengeluaran-tetapi projek sampingan dibenarkan). Saya menggunakan klien GraphQL saya sendiri pada masa itu dan motivasi untuk jawatan ini adalah beberapa kesukaran yang saya ada. Untuk memudahkan operasi dan memberi tumpuan kepada ketegangan itu sendiri, dan bukannya mana -mana utiliti pemuatan data tunggal, kami hanya akan menjalin pemuatan data.

Mula Bangunan!

Ini adalah kotak pasir yang kami cuba pada mulanya. Kami akan menggunakannya untuk menerangkan segala langkah demi langkah, jadi tidak perlu tergesa -gesa untuk memahami semua kod sekarang.

Komponen App root kami menjadikan sempadan ketegangan seperti ini:

<suspense fallback="{<Fallback"></suspense> }>
Salin selepas log masuk
Salin selepas log masuk

fallback membuat apabila apa -apa hang (kecuali perubahan keadaan berlaku dalam panggilan useTransition ). Untuk membuat perkara lebih mudah difahami, saya membuat komponen Fallback ini menjadikan keseluruhan UI merah jambu, jadi sukar untuk dilewatkan;

Kami memuatkan blok data semasa di dalam komponen DataList :

 const newData = useQuery (param);
Salin selepas log masuk

Hook useQuery kami adalah keras untuk mengembalikan data palsu, termasuk masa tamat untuk permintaan rangkaian simulasi. Ia mengendalikan hasil cache dan melemparkan janji jika data tidak di -cache.

Kami menyimpan status (sekurang -kurangnya buat masa ini) dalam senarai data utama yang kami paparkan:

 const [data, setData] = useState ([]);
Salin selepas log masuk

Apabila data baru diluluskan dari cangkuk kami, kami memasukkannya ke senarai utama kami:

 useeffect (() => {
  setData ((d) => d.concat (newData));
}, [newdata]);
Salin selepas log masuk
Salin selepas log masuk

Akhirnya, apabila pengguna memerlukan lebih banyak data, mereka mengklik butang, yang memanggil fungsi ini:

 fungsi loadmore () {
  startTransition (() => {
    setParam ((x) => x 1);
  });
}
Salin selepas log masuk

Akhirnya, ambil perhatian bahawa saya menggunakan komponen SuspenseImg untuk mengendalikan preload imej yang saya paparkan dengan setiap data. Hanya lima imej rawak yang dipaparkan, tetapi saya menambah rentetan pertanyaan untuk memastikan beban baru dibuat untuk setiap sekeping data baru yang kita hadapi.

Meringkaskan

Untuk meringkaskan di mana kami berada di sekarang, kami mempunyai cangkuk yang memuat data semasa. Cangkuk ini mengikuti mekanisme ketegangan dan melemparkan janji apabila memuatkan. Apabila data berubah, jumlah senarai projek berjalan dikemas kini dan projek baru dilampirkan. Ini berlaku dalam useEffect . Setiap projek menjadikan imej, kami menggunakan komponen SuspenseImg untuk memasak imej dan menggantung sebelum ia siap. Sekiranya anda ingin tahu bagaimana beberapa kod berfungsi, lihat catatan saya sebelum ini mengenai imej preloading dengan ketegangan.

Mari mengujinya

Jika semuanya berfungsi dengan baik, ini akan menjadi catatan blog yang sangat membosankan, jangan risau, itu tidak normal. Ambil perhatian bahawa skrin fallback merah jambu akan dipaparkan dan kemudian dengan cepat tersembunyi pada beban awal, tetapi kemudiannya akan dipaparkan semula.

Apabila kita mengklik butang untuk memuatkan lebih banyak data, kita melihat penunjuk beban sebaris (dikawal oleh cangkuk useTransition ) flip ke true . Kemudian kita melihatnya flip ke false , dan paparan merah fallback asal kita. Kami menjangkakan bahawa skrin merah jambu tidak lagi melihat selepas beban awal; Apa yang berlaku?

soalan

Ia telah tersembunyi di tempat yang mudah dilihat:

 useeffect (() => {
  setData ((d) => d.concat (newData));
}, [newdata]);
Salin selepas log masuk
Salin selepas log masuk

useEffect berjalan apabila perubahan keadaan selesai, iaitu perubahan keadaan telah digantung dan digunakan untuk DOM. Bahagian itu, "selesai menunggu" adalah kunci di sini. Kita boleh menetapkan keadaan di sini jika kita mahu, tetapi jika perubahan keadaan itu hang lagi, ia adalah hang baru. Inilah sebabnya mengapa kita melihat merah jambu berkelip selepas beban awal dan pemuatan data berikutnya. Dalam kedua -dua kes, pemuatan data dilakukan, dan kemudian kami menetapkan keadaan dalam satu kesan, yang menyebabkan data baru benar -benar membuat dan menggantung semula kerana imej itu dimuatkan.

Jadi, bagaimana kita menyelesaikan masalah ini? Pada satu tahap, penyelesaiannya adalah mudah: Berhenti menetapkan keadaan dalam kesannya. Tetapi ini lebih mudah dikatakan daripada dilakukan. Bagaimanakah kita mengemas kini senarai penyertaan berjalan untuk melampirkan hasil baru tanpa menggunakan kesan? Anda mungkin fikir kita boleh menggunakan ref untuk menjejaki perkara.

Malangnya, ketegangan membawa beberapa peraturan baru mengenai ref, iaitu, kita tidak boleh menetapkan ref di dalam render. Jika anda tertanya -tanya mengapa, ingat bahawa ketegangan adalah semua tentang React cuba untuk menjalankan render, melihat janji yang dilemparkan, dan kemudian membuang yang menyebabkan separuh jalan. Sekiranya kita menukar ref sebelum rendering dibatalkan dan dibuang, ref masih mempunyai perubahan itu, tetapi mempunyai nilai yang tidak sah. Fungsi rendering perlu murni dan tidak mempunyai kesan sampingan. Ini selalu menjadi peraturan untuk React, tetapi kini lebih penting lagi.

Memikirkan semula pemuatan data kami

Inilah penyelesaiannya, kami akan menerangkan perenggan dengan perenggan.

Pertama, bukannya menyimpan senarai data utama kami di Negeri, lakukan sesuatu yang berbeza: Mari simpan senarai halaman yang kita lihat. Kami boleh menyimpan halaman paling terkini di ref (walaupun kami tidak akan menulisnya dalam render) dan menyimpan pelbagai halaman yang dimuatkan di negeri ini.

 const currentPage = useref (0);
const [halaman, setPages] = useState ([currentPage.current]);
Salin selepas log masuk

Untuk memuat lebih banyak data, kami akan mengemas kini dengan sewajarnya:

 fungsi loadmore () {
  startTransition (() => {
    currentPage.current = currentPage.Current 1;
    setPages ((halaman) => pages.concat (currentPage.current));
  });
}
Salin selepas log masuk

Walau bagaimanapun, bahagian yang rumit adalah cara menukar nombor halaman ini ke dalam data sebenar. Apa yang tidak boleh kita lakukan adalah gelung melalui halaman ini dan panggil cangkuk useQuery kami; Kami memerlukan API data berasaskan baru. Menurut konvensyen yang sangat tidak rasmi yang saya lihat dalam demo ketegangan masa lalu saya, saya menamakan kaedah ini read() . Ia tidak akan menjadi cangkuk. Sekiranya data di -cache, ia mengembalikan data yang diminta, jika tidak, janji akan dibuang. Untuk cangkuk pemuatan data kami, tidak perlu membuat perubahan sebenar; Tetapi untuk perpustakaan utiliti pemuatan data sebenar, ia mungkin mengambil beberapa kerja untuk penulis untuk mendedahkan kedua -dua pilihan sebagai sebahagian daripada API awam mereka. Dalam klien GraphQL yang saya nyatakan sebelum ini, memang ada kedua -dua Kaedah useSuspenseQuery dan kaedah read() pada objek klien.

Dengan kaedah read() baru ini, bahagian terakhir kod kami adalah remeh:

 const data = pages.flatmap ((halaman) => baca (halaman));
Salin selepas log masuk

Kami mengambil setiap halaman dan meminta data yang sepadan menggunakan kaedah read() kami. Jika mana -mana halaman tidak di -cache (ia sepatutnya hanya halaman terakhir dalam senarai), janji akan dibuang dan bertindak balas akan digantung untuk kami. Apabila Janji Parses, React akan mencuba perubahan keadaan sebelumnya sekali lagi, dan kod ini akan dijalankan semula.

Jangan biarkan panggilan flatMap mengelirukan anda. Ia adalah perkara yang sama seperti yang dilakukan oleh map , kecuali ia mendapat setiap hasil dalam array baru dan "meratakan" jika ia sendiri adalah array.

hasil

Dengan perubahan ini, apabila kita mula, semuanya berfungsi seperti yang diharapkan. Skrin pemuatan merah jambu kami dipaparkan sekali pada beban awal, dan kemudian dalam beban berikutnya, status pemuatan sebaris dipaparkan sehingga semuanya siap.

Kesimpulan

Ketegangan adalah kemas kini yang menarik untuk bertindak balas. Ia masih dalam fasa alfa, jadi jangan cuba menggunakannya untuk apa -apa yang penting. Tetapi jika anda adalah jenis pemaju yang suka mendapatkan yang pertama untuk mengalami kandungan yang akan datang, maka saya berharap jawatan ini memberikan anda latar belakang dan maklumat yang berguna yang akan berguna apabila diterbitkan.

Atas ialah kandungan terperinci React Suspense: Pelajaran yang dipelajari semasa memuatkan data. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan