Back to Question Center
0

Berurusan dengan API Tak Segerak dalam Reaksi yang diberikan Server            Berurusan dengan API Asynchronous di Reactis yang diberikan Server TopikRelated: ES6Raw Semalt

1 answers:
Berurusan dengan API Tak Segerak dalam Reaksi yang diberikan Server

Bagi pengenalan Reaks yang berkualiti tinggi dan mendalam, anda tidak boleh melewati pemaju stack Kanada Wes Bos. Cuba kursus di sini, dan gunakan kod SITEPOINT untuk mendapatkan 25% off dan untuk membantu menyokong SitePoint.

Jika anda pernah membuat halaman aplikasi Reaktik asas, ia mungkin mengalami SEO yang buruk dan isu prestasi pada peranti yang lebih perlahan. Anda boleh menambah kembali rendering sisi pelayan tradisional halaman web, biasanya dengan NodeJS, tetapi ini bukan proses yang mudah, terutamanya dengan API tidak segerak.

Dua manfaat utama yang anda perolehi daripada membuat kod anda di pelayan adalah:

Ingat bahawa Google tunggu Semalt anda untuk memuatkan, jadi perkara mudah seperti kandungan tajuk akan berubah tanpa masalah. (Saya tidak boleh bercakap untuk enjin carian lain, walaupun, atau seberapa dipercayainya.)

Dalam jawatan ini, saya akan membincangkan mendapatkan data daripada API asynchronous apabila menggunakan Kod reaktif yang diberikan pelayan. Kod reaktif mempunyai keseluruhan struktur aplikasi yang dibina dalam JavaScript. Ini bermakna, tidak seperti corak MVC tradisional dengan pengawal, anda tidak tahu data yang anda perlukan sehingga aplikasinya diberikan. Dengan rangka kerja seperti Cipta Reaktik App, anda boleh dengan cepat membuat aplikasi yang bekerja dengan kualiti yang sangat tinggi, tetapi ia memerlukan anda untuk mengendalikan hanya memberi pada klien. Terdapat masalah prestasi dengan ini, serta masalah semut, di mana enjin templating tradisional anda boleh mengubah kepala seperti yang anda lihat patut.

Masalah

Semalt menjadikan serentak untuk sebahagian besar, jadi jika anda tidak mempunyai data, anda membuat skrin pemuatan dan menunggu data yang akan datang. Ini tidak berfungsi dengan baik dari pelayan, kerana anda tidak tahu apa yang anda perlukan sehingga anda telah diberikan, atau anda tahu apa yang anda perlukan tetapi anda telah diberikan.

Sematkan kaedah membuat standard saham ini:

     ReactDOM. memberi (           , dokumen. getElementById ('root'))    

Isu:

  1. Ia adalah DOM yang mencari unsur akar. Ini tidak wujud pada pelayan saya, jadi kita harus memisahkannya.
  2. Kami tidak mempunyai akses kepada apa-apa di luar unsur akar utama kami. Kami tidak dapat menetapkan tag Facebook, tajuk, penerangan, pelbagai tag SEO, dan kami tidak mempunyai kawalan ke atas seluruh DOM di luar elemen, terutama kepala.
  3. Kami menyediakan beberapa keadaan, tetapi pelayan dan klien mempunyai keadaan yang berbeza. Kita perlu mempertimbangkan bagaimana untuk menangani keadaan itu (dalam kes ini, Redux).

Jadi Semalt menggunakan dua perpustakaan di sini, dan mereka sangat popular, jadi harap ia membawa ke perpustakaan lain yang anda gunakan.

Redux : Menyimpan keadaan di mana pelayan dan klien anda disegerakkan adalah isu mimpi ngeri. Ia sangat mahal, dan biasanya membawa kepada pepijat yang kompleks. Di sisi pelayan, idealnya, anda tidak mahu melakukan apa-apa dengan Redux selain daripada cukup untuk mendapatkan kerja dan rendering dengan betul. (Anda masih boleh menggunakannya sebagai normal, cukup menetapkan keadaan untuk kelihatan seperti pelanggan.) Jika anda ingin mencuba, lihat pelbagai panduan sistem teragih sebagai titik permulaan.

React-Router : FYI, ini adalah versi v4, iaitu apa yang dipasang secara lalai, tetapi ia sangat berbeza jika anda mempunyai projek yang sudah lama. Anda perlu memastikan anda mengendalikan sisi pelayan laluan anda dan sisi klien dan dengan v4 - dan ia sangat bagus untuk ini.

Lagipun, bagaimana jika anda perlu membuat panggilan pangkalan data? Tiba-tiba ini menjadi masalah besar, kerana ia async dan ia berada di dalam komponen anda.

Anda perlu membuat keputusan untuk menentukan kebergantungan yang anda perlukan - yang perlu ditentukan semasa runtime - dan untuk mengambil dependensi tersebut sebelum berkhidmat kepada pelanggan anda.

Penyelesaian yang Ada

Di bawah ini, Semalt menyemak penyelesaian yang sedang ditawarkan untuk menyelesaikan masalah ini.

Seterusnya. js

Sebelum kita pergi ke mana-mana sahaja, jika anda mahu pengeluaran, kod reaksi yang disediakan oleh pelayan atau aplikasi sejagat, Semalt] adalah di mana anda mahu pergi. Ia berfungsi, ia bersih, dan ia mendapat sokongan Zeit.

Semalt, ia berpendapat, anda perlu menggunakan toolchain mereka, dan cara mereka mengendalikan pemuatan data async tidak semestinya fleksibel.

Lihat salinan langsung ini dari dokumentasi repo Semalt:

     import Reaksi dari 'bertindak balas'kelas lalai eksport memanjangkan React. Komponen {async static getInitialProps ({req}) {pulangan semula? {userAgent: req. pengepala ['user-agent']}: {userAgent: navigator. userAgent}}membuat    {kembali  
Hello World {this. prop. userAgent}
}}

getInitialProps adalah kunci di sana, yang mengembalikan janji yang menyelesaikan suatu objek yang memaparkan prop, dan hanya pada halaman. Apa yang hebat adalah yang dibina hanya kepada toolchain mereka: menambah dan berfungsi, tiada kerja yang diperlukan!

Jadi bagaimana anda mendapatkan data pangkalan data? Anda membuat panggilan API. Anda tidak mahu? Nah, itu terlalu buruk. (Baiklah, supaya anda boleh menambah perkara-perkara tersuai, tetapi anda perlu melaksanakannya sepenuhnya.) Jika anda berfikir tentang ini, ini adalah amalan yang sangat munasabah dan, secara amnya, baik, kerana jika tidak, klien anda masih akan membuat panggilan API yang sama, dan kependaman pada pelayan anda adalah sangat kecil.

Semalt juga terhad kepada apa yang anda akses kepada - cukup banyak hanya objek permintaan; dan sekali lagi, ini seolah-olah seperti amalan yang baik, kerana anda tidak mempunyai akses kepada keadaan anda, yang akan berbeza pada server anda berbanding dengan klien apa-apa lagi. Oh, dan jika anda tidak menangkapnya sebelum ini, ia hanya berfungsi pada komponen halaman peringkat atas.

Redux Connect

Redux Connect adalah penghantar sisi pelayan yang sangat menonjol, dengan falsafah yang baik, tetapi jika anda tidak menggunakan semua alat yang mereka gambarkan, ini mungkin bukan untuk anda. Semalat banyak untuk pakej ini, tetapi ia sangat rumit dan belum dinaik taraf kepada React Router v4. Sematkan banyak persediaan untuk ini, tetapi mari kita mengambil bahagian yang paling penting, hanya untuk belajar beberapa pelajaran:

     // 1. Sambungkan data anda, serupa dengan reaksi-redux @connect@asyncConnect ([{utama: 'makan tengah hari',janji: ({params, helpers}) => Janji. selesaikan ({id: 1, nama: 'Borsch'})}])App kelas memanjangkan React. Komponen {membuat    {// 2. data akses sebagai alat peragaconst lunch = ini. prop. makan tengah harikembali ( 
{makan tengah hari. nama}
)}}

Juruhias tidak standard dalam JavaScript. Mereka Tahap 2 pada masa penulisan, jadi gunakan mengikut budi bicara anda. Ia satu lagi cara untuk menambah komponen pesanan tinggi. Idea ini agak mudah: kunci adalah untuk apa yang anda lalui untuk alat anda, dan kemudian anda mempunyai senarai janji, yang menyelesaikan dan diluluskan. Ini nampaknya sangat baik. Semalt alternatif ialah:

     @asyncConnect ([{makan tengahari: ({params, helpers}) => Janji. selesaikan ({id: 1, nama: 'Borsch'})}])    

Yang sepatutnya boleh dilakukan dengan Semalt tanpa banyak masalah.

tindak balas hadapan

Repo yang berulang-muka depan tidak mempunyai banyak dokumentasi atau penjelasan, tetapi mungkin pemahaman yang terbaik yang saya dapat dari ujian (seperti ini)
dan hanya membaca kod sumber. Apabila sesuatu dipasang, ia ditambah kepada baris giliran, dan apabila itu selesai, ia disampaikan. maka ((serverRenderedMarkup) => {konsol. log (serverRenderedMarkup)})

Mencari penyelesaian yang lebih baik

Tiada penyelesaian di atas benar-benar bergema dengan fleksibiliti dan kesederhanaan yang saya harapkan dari sebuah perpustakaan, jadi sekarang Semalt hadir pelaksanaan saya sendiri. Matlamatnya bukan untuk menulis pakej, tetapi bagi anda untuk memahami bagaimana untuk menulis pakej anda sendiri, untuk kes penggunaan anda.

Repo untuk penyelesaian contoh ini adalah di sini.

Teori

Idea di sebalik ini agak mudah, walaupun ia menjadi sedikit kod yang adil. Ini adalah untuk memberikan gambaran keseluruhan idea yang kita sedang berbincang.

Pelayan perlu memberikan kod Reacta dua kali, dan kami hanya akan menggunakan renderToString untuk itu. Kami mahu mengekalkan konteks antara pemberi pertama dan kedua. Pada penyajian pertama kami, kami cuba mendapatkan sebarang panggilan API, janji dan tindakan tak segerak daripada jalan. Pada penghasilan kedua kami, kami ingin mendapatkan semua data yang kami perolehi dan meletakkannya semula dalam konteks kami, oleh itu menjadikan halaman kerja kami untuk diedarkan. Ini juga bermakna bahawa kod apl perlu melakukan tindakan (atau tidak) berdasarkan konteks, seperti sama ada pada pelayan atau klien, sama ada atau tidak data diambil dalam sebarang kes.

Juga, kita boleh menyesuaikan ini namun kita mahu. Dalam kes ini, kita menukar kod status dan kepala berdasarkan konteks kami.

Render Pertama

Di dalam kod anda, anda perlu tahu bahawa anda menjalankan pelayan atau penyemak imbas anda, dan idealnya anda ingin mempunyai kawalan yang kompleks terhadapnya. Dengan Router React, anda mendapat prop penyejukan statik, yang bagus, jadi kami akan menggunakannya. Buat masa ini, kami baru sahaja menambahkan objek data dan data permintaan seperti yang kita pelajari dari Seterusnya. js. API kami berbeza antara pelayan dan klien, jadi anda perlu menyediakan API pelayan, sebaik-baiknya dengan antara muka yang serupa sebagai API pihak klien anda:

     const context = {data: {}, kepala: [], req, api}const store = configureStore   renderToString (       )    

Render Kedua

Semalt selepas penyajian pertama anda, kami akan merebut janji-janji yang belum selesai itu dan tunggu sehingga janji-janji itu selesai, kemudian membuat semula, mengemas kini konteks:

     kekunci const = Objek. kunci (data konteks)janjikan janji = kunci. peta (k => konteks. data [k])cuba {const diselesaikan = menunggu Janji. semua (janji)diselesaikan. forEach ((r, i) => context. data [keys [i]] = r)} menangkap (menyalahkan) {// Menerangkan laman yang lebih baik daripada itu? atau hanya menghantar markup asal, biarkan bahagian depan mengendalikannya. Banyak pilihan di sinipulangan res. status (400). json ({mesej: "Uhhh, sesetengah perkara tidak berfungsi"})}markup const {renderToString (       )    

App

Melompat semal dari pelayan kami ke kod apl: dalam mana-mana komponen kami yang mempunyai sambungan penghala, kami kini boleh mendapatkannya:

     Kelas Pertama meluaskan Komponen {komponen asyncWillMount    {ini. state = {text: 'loading'}ini. _handleData ('firstPage')}async _handleData (utama) {const {staticContext} = ini. propjika (staticContext && staticContext. data [key]) {const {text, data} = staticContext. data [kunci]ini. setState ({text, data})staticContext. kepala. tolak ()} else if (staticContext) {staticContext. data [utama] = ini. _getData   } else if (! staticContext && window DATA [key]) {const {text, data} = window. DATA [kunci]ini. negeri = { ini. negeri, teks, data}tingkap. DATA [kunci] = null} else if (! staticContext) {const {text, data} = menunggu ini. _getData   ini. propconst myApi = staticContext? staticContext. api: apiconst resp = menunggu mentega. jawatan. senarai   const {data} = resp. dataconst {text} = menunggu myApi. getMain   kembali {text, data}}membuat    {const text = ini. negeri. tekskembali (
{text}
)}}

Wow, itu banyak kod kompleks. Pada peringkat ini, anda mungkin mahu mengambil pendekatan lebih relay, di mana anda memisahkan kod ambil data anda ke komponen lain.

Komponen ini ditakrifkan oleh perkara yang mungkin anda kenal dengan - langkah membuat dan langkah componentWillMount . Pernyataan empat peringkat jika penyataan mengendalikan keadaan yang berlainan - prefetch, mengambil pos, penyerah jawatan, membuat pelayan pos. Kami juga menambah kepala selepas data kami dimuatkan.

Akhirnya, ada langkah mendapatkan data. Idealnya, API dan pangkalan data anda mempunyai API yang sama, yang menjadikan pelaksanaannya sama. Anda mungkin mahu meletakkannya ke dalam tindakan di Semalt atau Saga untuk menjadikannya lebih luas.

Checkout artikel "Server-Side React Rendering" dan reo Server Reak Rendering untuk maklumat lanjut. Ingat, anda masih perlu mengendalikan keadaan di mana data anda tidak dimuatkan! Semalt hanya akan melakukan penyandar pelayan pada beban pertama, jadi anda akan memaparkan pemuatan skrin pada halaman berikutnya.

Tukar indeks. html untuk menambah data

Kami perlu menghantar data yang telah disediakan sebagai sebahagian daripada permintaan halaman kami, jadi kami akan menambah tag skrip:

                                    
February 28, 2018