Pentru orice aplicație React care depășește un nivel simplu, organizarea în diverse pagini devine esențială. În acest context, implementarea unui sistem de rutare în React este necesară.
Deși poate părea complicat la început, acest ghid vă va familiariza cu elementele de bază. Scopul nostru este să construim împreună o aplicație funcțională care să utilizeze rutarea.
Ce este Rutarea în React (Rutarea pe Partea Clientului)
Rutarea în React reprezintă o formă de rutare pe partea client, specifică aplicațiilor create cu React. Această metodă este o alternativă la rutarea pe partea serverului. În abordarea server-side, browserul trimite o cerere GET serverului web de fiecare dată când navigăm la o altă pagină. Această solicitare poate dura câteva momente până primește un răspuns.
Pentru o aplicație web în care schimbăm frecvent paginile, aceste întârzieri pot afecta negativ experiența utilizatorului. Rutarea pe partea client elimină aceste întârzieri. În loc să primească HTML de la server, aplicația folosește JavaScript pentru a genera dinamic conținutul HTML pentru diferite pagini.
Tot ce trebuie este un singur fișier `index.html` ca punct de intrare. Acest fișier încarcă codul JavaScript necesar. Apoi, pachetul JavaScript se ocupă de afișarea paginilor prin manipularea DOM, gestionând rutele și implementând funcționalitățile aplicației.
Deoarece serverul returnează doar pagina `index.html`, aceste tipuri de aplicații sunt cunoscute ca aplicații cu o singură pagină.
Avantajele Rutării pe Partea Clientului
- Asigură o experiență de utilizare superioară, datorită navigării rapide și a răspunsului imediat al aplicației. Spre deosebire de rutarea pe server, unde fiecare navigare implică o solicitare de rețea cu o anumită latență.
- Permite crearea aplicațiilor offline, prin stocarea codului necesar în memoria cache locală. Acest lucru crește accesibilitatea aplicațiilor și oferă funcționalitate chiar și fără conexiune la internet.
- Reduce consumul de date, deoarece solicitările de rețea sunt semnificativ diminuate, iar anumite fișiere sunt stocate local.
- Scade presiunea asupra serverului, care trebuie să redea aplicația doar o singură dată, în contrast cu rutarea pe server, unde aplicația este redată continuu.
În continuare, vom analiza cum se implementează rutarea în React.
Cum se Implementează Rutarea în React
În scopul acestui ghid, vom construi o aplicație simplă de luare a notițelor. Aceasta va fi structurată în mai multe pagini. Vom folosi React Router DOM pentru a implementa rutarea pe partea client, permițând navigarea între pagini. Ne vom concentra în special pe aspectele legate de rutare, fără a dezvolta toate funcționalitățile aplicației.
Cerințe Preliminare
Pentru a parcurge acest ghid, este necesar să aveți cunoștințe despre HTML, JavaScript și React. De asemenea, trebuie să aveți instalate Node.js și NPM. Acestea pot fi instalate simultan prin descărcarea Node.js de pe pagina oficială. Alternativ, puteți urmări instrucțiunile din videoclipul YouTube încorporat.
Ce Vom Construi
Aplicația noastră va cuprinde mai multe pagini, între care veți putea naviga folosind sistemul de rutare în React. Mai jos sunt prezentate modelele pentru pagini:
Pagina principală este afișată la ruta „/”.
Pagina „Despre” este accesibilă la ruta „/about”.
Pagina cu lista de notițe se găsește la ruta „/note”.
Pagina pentru adăugarea unei noi notițe este la ruta „/note/new”.
Puteți vizualiza detaliile fiecărei notițe pe pagina aferentă, accesibilă la ruta ‘/routes/
Primii Pași
Pentru a începe, creați un nou proiect React. Vom folosi Vite, deci comanda de inițializare a unui proiect nou este următoarea:
npm create vite@latest scribbble --template react
Am denumit proiectul „scribbble” și am specificat React ca șablon. Apoi, vom deschide VS Code utilizând comenzile:
cd scribbble code .
După deschiderea VS Code, reveniți la terminal și instalați `react-router-dom`. Acest pachet simplifică implementarea rutării în aplicațiile React.
npm install react-router-dom
Vom crea un fișier pentru a stoca notițele. Creați `src/notes.js` și introduceți codul:
const notes = [ { id: 1, title: "Note 1", body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", }, { id: 2, title: "Note 2", body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", }, { id: 3, title: "Note 3", body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", }, ]; export default notes;
Ștergeți fișierul `src/App.css`, deoarece nu-l vom utiliza. Asigurați-vă și că eliminați importul pentru `App.css` din fișierul `App.jsx`.
Înlocuiți conținutul din `index.css` cu:
:root{font-family:Inter,system-ui,Avenir,Helvetica,Arial,sans-serif;font-weight:400;color:#404040}*{margin:0;padding:0}.nav-container{display:flex;justify-content:space-between;padding:15px 30px}.home-buttons,.nav{display:flex;gap:10px}a{text-decoration:none;color:inherit;font-weight:600}h1{font-size:63px;margin:20px 0}input,textarea{border:1px solid #f1f1f1;background-color:#fafafa;outline:0;padding:10px;width:100%}textarea{resize:none;font-family:inherit}.container{padding:15px}.primary{background-color:#8a2be2;color:#fff}.secondary{background-color:#eee}.button{padding:15px 30px;font-size:16px;border:none;font-weight:700;border-radius:7px;cursor:pointer}.home-container{height:300px;display:flex;flex-direction:column;align-items:center;justify-content:center}.new-note-container{padding:20px}.new-note-form{display:flex;flex-direction:column;align-items:center;width:500px;gap:20px;margin:auto;border-radius:7px;padding:20px 30px}.notes-list{display:grid;grid-template-columns:1fr 1fr 1fr;gap:30px;padding:0 60px}.note{border:1px solid #d3d3d3;padding:15px;border-radius:7px}.note h2{font-size:1rem;margin-bottom:10px}.note p{color:#585858;font-size:.9rem;cursor:pointer}.note-container{display:flex;align-items:center;justify-content:center;padding:50px}.note-content{width:500px}
Creați următoarele fișiere pentru paginile pe care le vom crea:
- `src/pages/Home.jsx`
- `src/pages/About.jsx`
- `src/pages/Note.jsx`
- `src/pages/NewNote.jsx`
- `src/pages/Notes.jsx`
De asemenea, creați fișierul pentru componenta Barei de Navigare, în `src/components/NavBar.jsx`.
Configurarea Rutării în React
Acum că aplicația este configurată, putem configura rutarea.
Deschideți fișierul `App.jsx` și ștergeți tot conținutul. Adăugați importurile în partea de sus:
import { BrowserRouter, Routes, Route } from "react-router-dom"; import { NavBar } from "./components/NavBar"; import { Home } from "./pages/Home"; import { About } from "./pages/About"; import { Notes } from "./pages/Notes"; import { Note } from "./pages/Note"; import { NewNote } from "./pages/NewNote";
Importăm componentele `BrowserRouter`, `Routes` și `Route` din `react-router-dom`. Acestea ne vor ajuta să configurăm rutele. Am importat, de asemenea, componenta `NavBar` și paginile necesare. Nu am implementat încă paginile, dar vom face acest lucru în curând.
Configurăm acum componenta aplicației:
export default App () { }
Adăugăm următorul marcaj în declarația `return`:
return ( <BrowserRouter> </BrowserRouter> )
Acesta afișează `BrowserRouter`, o componentă React furnizată de `react-router-dom`. Această componentă configurează un router care funcționează în browser. Aplicația noastră va fi conținută în interiorul acestor etichete.
Adăugăm bara de navigare și creăm o componentă `Routes`:
return ( <BrowserRouter> <NavBar /> <div className="container"> <Routes> </Routes> </div> </BrowserRouter> );
În interiorul `BrowserRouter`, am inclus `NavBar`. Vom defini această componentă mai târziu, dar ea va oferi legături în partea de sus a fiecărei pagini. În loc să creăm separat bare de navigare pentru fiecare pagină, am creat o componentă `NavBar` reutilizabilă.
Am adăugat și un element `container` pentru a aplica stiluri, dar acesta nu este esențial pentru rutare.
În interiorul containerului, se află componenta `Routes`. Aici vom afișa pagini diferite, în funcție de ruta curentă din browser. Tot ce este inclus în componenta `Routes` va fi actualizat de fiecare dată când ruta se modifică.
În final, adăugăm rute pentru diferite pagini:
return ( <BrowserRouter> <NavBar /> <div className="container"> <Routes> <Route path="/" Component={Home} /> <Route path="about" Component={About} /> <Route path="notes" Component={Notes}> <Route path="new" Component={NewNote} /> <Route path=":id" Component={Note} /> </Route> </Routes> </div> </BrowserRouter> );
Componenta `Home` va fi afișată când calea este „/”, iar componenta `About` va fi afișată la ruta „/about”. Componenta `Notes` va fi afișată la ruta „/notes”. Am definit, de asemenea, rutele „/notes/new” și „/notes/:id” ca rute imbricate.
Rute Imbricate – Explicații
O rută poate conține alte rute, numite rute imbricate. Calea către aceste rute va fi obținută prin concatenarea cu calea părinte. De exemplu, „notes” și „new” vor fi combinate în „/notes/new”.
Când un utilizator navighează la o rută părinte, doar componenta corespunzătoare rutei părinte este afișată. Totuși, când navighează la o rută imbricată, atât componenta părinte, cât și cea imbricată sunt afișate.
Pentru a afișa ambele componente, componenta `Notes` trebuie să includă o componentă `Outlet` care specifică unde va fi încorporată componenta `Note`. Veți vedea acest lucru când vom începe să creăm paginile.
Rute Dinamice
Până acum, am specificat rute literale. De exemplu, rutele „/” și „despre”. React-router-dom permite specificarea rutelor dinamice, care conțin porțiuni ce pot fi asociate cu un parametru. Când ruta se potrivește, parametrul este transmis paginii.
De exemplu, în ruta părinte „posts”, avem o rută imbricată care conține o porțiune dinamică, specificată de `:id`. Această rută acceptă orice text în locul `:id`, textul devenind disponibil componentei `Note` ca proprietate `id`.
Construirea Barei de Navigare
Folosim componente `Link` în loc de etichetele `` standard pentru navigare, folosind react-router-dom. Prin urmare, bara noastră de navigare ar trebui să arate astfel:
import { Link } from "react-router-dom"; export function NavBar() { return ( <div className="nav-container"> <Link to="/">Scribbble</Link> <nav className="nav"> <Link to="/about">About</Link> <Link to="/notes">Notes</Link> <Link to="/notes/new">New Note</Link> </nav> </div> ); }
Adăugați acest cod în `src/components/NavBar.jsx`.
Construirea Paginilor
Acum, vom construi paginile. Pentru pagina principală, introduceți următorul cod în `src/pages/Home.jsx`.
import { useNavigate } from "react-router-dom"; export function Home() { const navigate = useNavigate(); return ( <div className="home-container"> <h1>Notes for professionals</h1> <div className="home-buttons"> <button onClick={() => { navigate("/notes/new"); }} className="button primary" > Start Scribbling </button> <button onClick={() => { navigate("/notes"); }} className="button secondary" > View Notes </button> </div> </div> ); }
Pe pagina principală, dorim să folosim butoane pentru navigare. Folosim hook-ul `useNavigate` pentru a naviga programatic. Am importat și am apelat acest hook în interiorul componentei `Home`. Valoarea returnată este o funcție folosită pentru navigare.
Definim acum pagina `About`. Adăugați următorul cod în `src/pages/About.jsx`.
export function About() { return ( <div> <h1>About</h1> <p>Simple Notes is the best note-taking application for professionals</p> </div> ); }
În continuare, definim pagina `Note`.
Această componentă trebuie să includă și o componentă `Outlet` pentru afișarea rutelor imbricate. Astfel, conținutul din `src/pages/Notes.jsx` va fi:
import { Outlet, useNavigate } from "react-router-dom"; import notes from "../notes"; export function Notes() { const navigate = useNavigate(); return ( <div> <Outlet /> <div className="notes-list"> {notes.map((note) => { return ( <div className="note" key={note.id} onClick={() => { navigate("/notes/" + note.id); }} > <h2>{note.title}</h2> <p>{note.body.slice(0, 100)}</p> </div> ); })} </div> </div> ); }
Acum definim pagina `Note`.
Această componentă va fi folosită pentru afișarea unei notițe individuale. Pentru a selecta notița afișată, componenta `Note` va accesa ID-ul specificat în porțiunea dinamică a rutei, folosind hook-ul `userParams`. Prin urmare, codul din `src/pages/Note.jsx` va fi:
import { useParams } from "react-router-dom"; import notes from "../notes"; export function Note() { const params = useParams(); const note = notes.find((note) => note.id == params.id); return ( <div className="note-container"> <div className="note-content"> <h2>{note.title}</h2> <p>{note.body}</p> </div> </div> ); }
În cele din urmă, creăm componenta `NewNote` în interiorul `src/pages/NewNote.jsx`, cu următorul cod:
export function NewNote() { return ( <div class="new-note-container"> <form class="new-note-form"> <h2>New Note</h2> <input type="text" name="title" placeholder="Note title" /> <textarea rows="10" placeholder="Note text" /> <button class="button primary">Save Note</button> </form> </div> ); }
În acest moment, tot codul aplicației este complet. Puteți rula aplicația cu `npm run dev`. Navigați prin diferite pagini și veți observa rapiditatea rutării pe partea clientului.
Dezavantajele Rutării pe Partea Clientului
În ciuda avantajelor, rutarea pe partea client prezintă și dezavantaje:
- Încărcarea inițială a paginii poate fi mai lentă, deoarece întreaga aplicație trebuie încărcată. Pachetul JavaScript poate fi mare, necesitând un timp de încărcare mai lung.
- Deoarece codul HTML este generat de JavaScript, pagina nu este optimizată pentru SEO.
- Aplicațiile se bazează pe JavaScript, deci browserele care nu suportă JavaScript sau care îl au dezactivat nu pot rula aplicația.
Concluzie
În acest articol, am abordat rutarea în React construind un proiect simplu. Deși nu am acoperit toate detaliile, acest ghid prezintă concepte importante folosite frecvent în proiecte. Pentru mai multe informații despre `react-router-dom`, consultați documentația oficială.
Vă recomandăm să citiți și acest articol despre bibliotecile de formulare în React.