Kami ada masalah, async sukar.
Bayangkan anda mempunyai API GET yang ringkas, carian yang menerima teks carian sebagai param. Anda memanggilnya menggunakan alat pilihan permintaan http anda dan mendapat janji, ia menyelesaikan kepada senarai apa sahaja yang anda cari.
Bagaimanakah saya boleh memanggilnya dalam komponen React?
Pertama sekali, adalah penting untuk melihat satu perkara, perkara yang saya nyatakan boleh dimodelkan sebagai:
result = await searchAPI(searchText);
Mari kita berkonsepkan di sini. Ini adalah terbitan. Untuk setiap versi searchText, anda boleh mendapatkan hasil yang berbeza. Tetapi terdapat beberapa masalah di sini:
Bagaimanakah saya boleh memanggilnya sebagai terbitan dalam React?
Menggunakan perpustakaan pihak ketiga, seperti TanStack Query dan SWR menyelesaikan masalah kami. Mereka memberi kami cangkuk yang boleh kami gunakan dalam komponen React, menerima keadaan dan prop kami dan mengira semula (mengambil semula) ke API apabila ia berubah. Lihat contoh ini:
const { data: searchResult, loading } = useQuery({queryKey: [search, searchText],queryFn: getSearch,});
Ok, kami menyelesaikan terbitan tak segerak, bukan?
Tidak juga.
Omong-omong, saya sentiasa mengesyorkan hanya menggunakan salah satu perpustakaan ini, ia hebat dan menjimatkan banyak masa dengan kes yang lebih kompleks (seperti mengambil semula, mencuba semula, kawalan cache dan lain-lain), tetapi kami tidak boleh bergantung pada satu pertiga -pihak untuk menyelesaikan masalah konseptual React.
Sekali lagi untuk kereaktifan, kita perlu mempunyai cara untuk menangani kes tak segerak dalam model terbitan. React sepatutnya memberi kita primitif untuk kes ini. Nah, sehingga versi 18 kami tidak memilikinya, tetapi dalam 19 ia berbeza.
React 19 memperkenalkan primitif baharu yang dipanggil penggunaan. Ya, penamaan itu sedikit mengelirukan, tetapi peranannya pada model kereaktifan React cukup penting. Dengan itu, kita boleh menyelesaikan janji semasa pemaparan komponen. Terbitan yang tiada.
Sebelumnya, satu-satunya cara untuk memanggil pengambilan semasa pemaparan komponen ialah menggunakan useEffect, panggil janji dan pada klausa kemudian, tetapkan keadaan dengan nilai yang datang sebagai respons. Itu berjaya, agaknya, tetapi kami menghadapi semua masalah menggunakan kesan untuk melakukannya.
Penggunaan primitif membolehkan kami menyelesaikan janji semasa pemaparan komponen, membolehkan kami menggunakan keadaan dan prop untuk mencipta janji, dan kemudian, menyelesaikan janji ini dan menggunakannya pada fungsi dan JSX kami.
const useCountTotal = (count: number) => { const countTotalPromise = useMemo(() => genericPromise(count), [count]); const result = use(countTotalPromise); return result; } function AsyncDerivation({count}: { count: number}) { const result = useCountTotal(count); return ( <div>Total count is: {result}</div> ) }
Pada masa ini saya menulis ini, kami belum mempunyai keluaran akhir React 19. Terdapat beberapa kaveat dan mungkin primitif akan berkembang pada masa hadapan untuk berfungsi di lebih banyak tempat.
Satu perkara khusus penggunaan primitif ialah ia perlu digunakan dengan Suspense dan terdapat sebab yang sangat baik untuk ini.
Idea konsep menunggu adalah bagus, tetapi ia mempunyai kelemahan apabila digabungkan dengan komponen React. Anda tidak boleh menggunakan await sahaja semasa pemaparan. React memanggil komponen untuk mendapatkan respons JSX dan menggunakannya pada aliran mereka untuk menghasilkan UI.
Jika kita boleh menghentikan segala-galanya dalam penantian, React tidak dapat mengakses anak-anak komponen itu dan meneruskan kerjanya sehingga penghujung pokok. Kami akan menghentikan aliran pemaparan dan menjadikan UI tidak dikemas kini dan pegun.
Bagaimana untuk menyelesaikannya?
Kita boleh lihat dua contoh yang saya gunakan dalam artikel ini. Yang pertama mengambil pendekatan mengembalikan bendera seperti memuatkan, tidak menyekat aliran render. Apabila janji telah diselesaikan, ia melemparkan pemaparan semula, mengemas kini bendera, pemuatan menjadi palsu dan data menerima data respons.
Pendekatan penggunaan adalah berbeza. Ia benar-benar berkelakuan seperti primitif menunggu, jadi aliran pemaparan komponen dihentikan di sana, sehingga resolusi.
Tunggu, tunggu, tunggu, awak kata itu masalah kan?
Dan di sini ia datang Suspense untuk keselamatan. Apabila anda menggunakan penggunaan primitif, ia akan dibalut dengan komponen Suspense, aliran pemaparan akan berhenti menunggu resolusi penggunaan dan pengguna mendapat sandaran yang diberikan pada UI (biasanya pemutar atau rangka pemuatan, sesuatu yang menunjukkan kami sedang memuatkan beberapa barangan di sana).
Apabila janji penggunaan diselesaikan, kami meneruskan pemaparan dan mengemas kini UI dengan sewajarnya. Tak perlu guna useEffect.
Penggunaan primitif akan sangat berguna untuk pengarang perpustakaan yang bertujuan untuk menggunakan Suspense dan berfungsi dengan tingkah laku tak segerak. Untuk pembangun apl, ia membetulkan satu lagi kes dalam model kereaktifan asas, yang sesuai dengan kes penggunaan mudah. Memandangkan ia membungkus janji, ia tidak terhad hanya kepada permintaan http, tetapi untuk semua kes async dan penggunaan API luaran, yang boleh menambah lebih banyak sumber pada ekosistem.
Atas ialah kandungan terperinci Derivasi Async dalam React. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!