Jika Anda mencoba menjelaskan secara singkat fungsi routing pada front-end aplikasi web, Anda dapat sampai pada kesimpulan bahwa setiap kerangka kerja populer memiliki gagasan yang sangat berbeda tentang ini. Bahkan membandingkan versi kerangka kerja yang sama, kita dapat menyimpulkan bahwa fungsi dan perutean API paling rentan terhadap perubahan (seringkali tanpa kompatibilitas ke belakang). Misalnya, perutean React versi ke-4 telah dirancang ulang secara radikal sehingga beberapa proyek populer di githab.com belum beralih ke versi ini.
Di balik semua ini, ada kecenderungan umum, yang, menurut pendapat saya, adalah bahwa fungsi perutean di banyak kerangka kerja front-end populer kelebihan beban. Dalam hal ini, ia menjadi sangat terhubung dengan komponen lain yang dapat diisolasi dari perutean (misalnya, navigasi, sejarah, tautan, dll.). Oleh karena itu, mungkin, banyak yang terbiasa dengan perasaan ketika penggunaan routing menjadi tidak nyaman, dan perluasannya tidak mungkin. Dibandingkan dengan komponen yang fleksibel dan dapat diperluas, perutean dalam kerangka front-end yang populer terlihat jauh lebih tidak nyaman dan tidak dapat dikembangkan sama sekali. Ini terutama berlaku untuk versi pertama (hingga 4) dari perutean di Bereaksi.
Dalam posting ini saya akan melihat beberapa poin historis yang mengarah ke keadaan ini dengan routing, serta penggunaan perpustakaan universal-router, bersama dengan React.
Apakah perlu routing?
Secara teknis, aplikasi web satu halaman dapat bekerja tanpa perutean. Misalnya, karena tidak ada perutean di aplikasi desktop. Semuanya akan berfungsi dengan baik jika aplikasi web satu halaman tidak tetap menjadi aplikasi browser web yang sama. Artinya, pengguna dapat menyegarkan halaman kapan saja dengan menekan tombol F5 atau dengan mengklik ikon "Reload" pada browser. Atau, pengguna dapat menggulir cerita ke depan atau ke belakang kapan saja dengan mengeklik ikon "Panah kiri" dan "Panah kanan", atau dengan menekan tombol "Backspace".
Oleh karena itu, untuk aplikasi satu halaman, perubahan komponen dan perubahan kondisi internal aplikasi harus selalu disertai dengan perubahan url.
Mengapa routing demikian?
Fungsi perutean dalam kerangka kerja populer untuk aplikasi web front-end, menurut pendapat saya, dipengaruhi oleh koneksi historisnya dengan perutean dalam aplikasi web klasik (dengan rendering server).
Awalnya, url adalah alamat web dari dokumen web statis, dan itu sangat sederhana. Selanjutnya, adaptasi arsitektur MVC ke web dimulai: Model 1 dan Model 2. Yang terakhir dari mereka termasuk front controller, yang kemudian dibagi menjadi dua bagian: routing (yang memilih controller yang diinginkan) dan controller itu sendiri, yang bekerja dengan model dan membuat tampilan. Seperti yang Anda lihat, dalam aplikasi web klasik, perutean menentukan tindakan (pengontrol) dan, secara tidak langsung (melalui pengontrol), menentukan tampilan yang harus ditampilkan di server.
Yaitu, arsitektur desktop diadaptasi pada satu waktu untuk bekerja dengan aplikasi web klasik di server, dan kemudian kembali ke depan aplikasi web dalam bentuk perutean, yang dibobot dengan fungsi yang diperlukan di sisi server.
Apa yang ditawarkan perpustakaan universal-router?
Perpustakaan universal-router menawarkan untuk membuang semua yang berlebihan dan hanya menyisakan bagian yang dapat digunakan dengan atau tanpa kerangka kerja saat merender baik pada klien dan di sisi server web (dalam aplikasi web universal / isomorfik).
Setelah menolak semua strata waktu, router universal hanya menawarkan satu fungsi yang jelas. Berdasarkan garis (saya tekankan garis lagi dan bukan objek sejarah, lokasi, dll.), Panggil fungsi asinkron, di mana string url yang diurai akan dikirim sebagai parameter aktual. Itu saja. Seperti apa bentuknya di React:
import React from 'react'; import UniversalRouter from 'universal-router'; import App from './App'; import Link from './Link'; const routes = { path: '/', async action({next}) { const children = await next(); return ( <App> {children} </App> ); }, children: [ { path: '', async action() { return ( <div>Root route go to <Link href='/test'>Test</Link></div> ); }, }, { path: '/test', async action({next}) { const children = await next(); return ( <App> {children} </App> ); }, children: [ { path: '', async action() { return ( <div>Test route return to <Link href='/'>Root</Link></div> ); }, }, ] }, ], }; export const basename = ''; const router = new UniversalRouter(routes, { baseUrl: basename }); export default router;
Rute bersarang juga didukung. Mereka didefinisikan di bidang anak-anak, dan Anda bisa mendapatkannya dengan memanggil fungsi asinkron () berikutnya.
Dan bagaimana cara kerjanya dengan React?
Tentukan metode navigasi () untuk riwayat, meskipun dalam banyak kasus cukup untuk menggunakan metode push asli ()
import { createBrowserHistory } from 'history' import parse from 'url-parse' import deepEqual from 'deep-equal' const isNode = new Function('try {return this===global;}catch(e){return false;}')
Kami juga membuat komponen Tautan yang akan memicu navigasi:
import React from 'react'; import {basename} from './router'; import history from './history'; function noOp(){}; const createOnClickAnchor = (callback) => { return (e) => { e.preventDefault(); history.navigate(e.currentTarget.getAttribute('href')); callback(e); }; }; export default ({href, onClick = noOp, children, ...rest}) => ( <a href={basename + href} onClick={createOnClickAnchor(onClick)} {...rest} > {children} </a> );
Sekarang Anda siap untuk membuat komponen:
import React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; import App from './App'; import * as serviceWorker from './serviceWorker'; import history from './history'; import router from './router'; const render = async (location) => { const element = await router.resolve(location); ReactDOM.render( element, document.getElementById('root'), ); }; render(history.location); history.listen(render);
Kode proyekTautan yang bermanfaat
1.
medium.com/@ippei.tanaka/universal-router-history-react-97ec79464573