Przewodnik po użyciu React-router-dom

W przypadku bardziej skomplikowanych aplikacji React, podział na liczne podstrony jest nieunikniony. W takiej sytuacji niezbędne staje się wprowadzenie mechanizmu routingu po stronie klienta.

Początkowo zagadnienie to może wydawać się trudne, lecz dzięki temu przewodnikowi zrozumiesz najważniejsze aspekty. W ramach tego tutoriala stworzymy aplikację wykorzystującą routing.

Czym jest routing w React (routing po stronie klienta)?

Routing w React to model routingu po stronie klienta, który jest wykorzystywany w aplikacjach opartych na React. Jest on alternatywą dla routingu po stronie serwera. W przypadku tego drugiego, przeglądarka przy każdym przejściu na inną podstronę generuje żądanie GET do serwera. Czas oczekiwania na odpowiedź może trwać kilka sekund.

W przypadku stron internetowych, gdzie często przeskakujemy między podstronami, opóźnienia te negatywnie wpływają na odbiór użytkownika. Dlatego routing po stronie klienta staje się rozwiązaniem. Zamiast przekazywać kod HTML do przeglądarki, aplikacja używa JavaScriptu do generowania kodu HTML dla różnych podstron.

Aby aplikacja mogła funkcjonować, potrzebny jest tylko plik Index.html jako punkt startowy. Ten punkt startowy uruchamia kod JavaScript, który z kolei generuje widok stron poprzez manipulację DOM, a także obsługę routingu i implementację logiki aplikacji.

Ponieważ serwer renderuje tylko plik Index.html, aplikacja jest nazywana aplikacją jednostronicową.

Korzyści z routingu po stronie klienta

  • Zapewnia lepsze wrażenia użytkownika, ponieważ nawigacja jest szybsza i bardziej płynna. W przypadku routingu po stronie serwera, każda zmiana strony oznacza ponowne żądanie do serwera, generując opóźnienia.
  • Umożliwia tworzenie aplikacji działających offline, ponieważ cały kod aplikacji może być przechowywany w lokalnej pamięci podręcznej. Dzięki temu możemy tworzyć aplikacje bardziej dostępne, także bez dostępu do internetu.
  • Aplikacja zużywa mniej danych, gdyż liczba żądań sieciowych jest znacznie mniejsza. Dane są pobierane tylko raz, a niektóre pliki są przechowywane w pamięci podręcznej.
  • Obciążenie serwera jest mniejsze, ponieważ serwer generuje widok aplikacji tylko raz. W przeciwieństwie do routingu po stronie serwera, gdzie serwer stale renderuje aplikację.

Przejdźmy teraz do omówienia sposobu wdrażania routingu w aplikacjach React.

Jak zaimplementować routing w React?

Na potrzeby tego tutoriala, zbudujemy prostą aplikację do tworzenia notatek, która będzie składać się z wielu podstron. Wykorzystamy routing po stronie klienta za pomocą React Router DOM, aby umożliwić nawigację między różnymi podstronami. Nie będziemy implementować pełnej funkcjonalności aplikacji, skupimy się głównie na routingu.

Wymagania wstępne

Aby skorzystać z tego tutoriala, wymagana jest znajomość HTML, JavaScript i React. Należy również mieć zainstalowane Node.js i NPM. Można je pobrać i zainstalować, pobierając Node.js ze strony internetowej lub postępować zgodnie z instrukcjami w filmie YouTube.

Co budujemy?

Aplikacja będzie składać się z kilku podstron. Za pomocą mechanizmu routingu, będziemy mogli swobodnie poruszać się między nimi. Poniżej prezentujemy projekty poszczególnych podstron.

Strona główna, która jest wyświetlana na ścieżce „/”.

Podstrona „O aplikacji” wyświetlana na ścieżce „/about”.

Podstrona z listą notatek, dostępna pod ścieżką „/notes”.

Podstrona do tworzenia nowych notatek dostępna pod ścieżką „/notes/new”.

Każda notatka będzie widoczna na osobnej podstronie w ramach podstrony „Notatki”. Ta strona będzie dostępna pod ścieżką „/routes/„, gdzie <id> to numer identyfikujący notatkę.

Pierwsze kroki

Zacznijmy od utworzenia nowego projektu React. Ja użyję Vite, zatem polecenie inicjujące nowy projekt wygląda następująco:

npm create vite@latest scribbble --template react

Nazwałem projekt „scribbble” i wybrałem szablon React. Następnie otworzę VS Code za pomocą tych poleceń:

cd scribbble
code .

Po otwarciu VS Code, wrócę do okna terminala i zainstaluję React-router-dom. Ten pakiet ułatwia wdrażanie routingu w aplikacjach.

npm install react-router-dom

Teraz utworzymy plik, w którym będą przechowywane nasze notatki. Utwórz plik src/notes.js i dodaj następujący kod:

const notes = [
  {
    id: 1,
    title: "Notatka 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: "Notatka 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: "Notatka 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;

Teraz usuń plik src/App.css. Nie będziemy go używać w tym projekcie. Pamiętaj również o usunięciu importu pliku App.css z pliku App.jsx.

Następnie zmień całą zawartość pliku Index.css na:

: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}

Następnie utwórz następujące pliki dla podstron, które będziemy tworzyć:

  • src/pages/Home.jsx
  • src/pages/About.jsx
  • src/pages/Note.jsx
  • src/pages/NewNote.jsx
  • src/pages/Notes.jsx

Utwórz również plik dla komponentu paska nawigacyjnego. Ten plik będzie znajdować się w src/components/NavBar.jsx

Konfiguracja routingu React

Po skonfigurowaniu aplikacji, skonfigurujemy mechanizm routingu.

Otwórz plik App.jsx i usuń z niego całą zawartość. Następnie dodaj na górze pliku następujące importy:

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";

Importujemy komponenty BrowserRouter, Routes i Route z pakietu React-router-dom. Będą one potrzebne do konfiguracji routera. Następnie importujemy pasek nawigacyjny NavBar z katalogu komponentów i podstrony z katalogu pages. Jeszcze nie zaimplementowaliśmy podstron, ale za chwilę to zrobimy.

Teraz skonfigurujemy komponent aplikacji:

export default App () {

}

Dodaj następujący kod w instrukcji return:

return (
    <BrowserRouter>
      
    </BrowserRouter>
)

To renderuje komponent BrowserRouter, udostępniany przez React-router-dom. Komponent ten konfiguruje router działający w przeglądarce. Cała nasza aplikacja będzie znajdować się w tych tagach.

Teraz dodamy pasek nawigacyjny i utworzymy komponent Routes.

return (
    <BrowserRouter>
      <NavBar />
      <div className="container">
        <Routes>
          
        </Routes>
      </div>
    </BrowserRouter>
  );

Wewnątrz elementu BrowserRouter dodaliśmy pasek nawigacyjny NavBar. Zdefiniujemy go później, ale będzie on generował linki do różnych stron. Zamiast tworzyć oddzielny pasek dla każdej strony, stworzymy jeden uniwersalny NavBar.

Następnie tworzymy element kontenera. Nie jest on wymagany do routingu, ale dodaliśmy go, aby zastosować odpowiednią stylistykę.

Wewnątrz kontenera umieszczamy komponent Routes. Tutaj będą renderowane różne podstrony, w zależności od bieżącej ścieżki przeglądarki. Wszystko wewnątrz komponentu Routes będzie ponownie renderowane za każdym razem, gdy zmieni się ścieżka.

Na koniec dodajemy trasy dla poszczególnych podstron.

  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>
  );

Komponent Home będzie renderowany, gdy ścieżka to „/”, a komponent About będzie renderowany na ścieżce „/about”. Komponent Notes będzie renderowany na trasie „/notes”. Zdefiniowaliśmy też zagnieżdżone trasy „/notes/new” i „/notes/:id”.

Wyjaśnienie tras zagnieżdżonych

Trasa może zawierać trasy wewnętrzne, które nazywamy trasami zagnieżdżonymi. Ścieżka do tych zagnieżdżonych tras jest łączona ze ścieżką nadrzędną, tworząc pełną ścieżkę. Na przykład ścieżki „notes” i „new” zostaną połączone w ścieżkę „/notes/new”.

W odniesieniu do sposobu renderowania komponentów, kiedy użytkownik przejdzie do ścieżki nadrzędnej, renderowany będzie tylko komponent nadrzędny. Jednak komponenty nadrzędne i zagnieżdżone będą renderowane razem podczas nawigacji do zagnieżdżonej trasy.

Aby renderować oba komponenty razem, komponent Notes musi renderować komponent Outlet, który określa miejsce, w którym zostanie osadzony komponent Note. Zobaczymy to później, kiedy zaczniemy tworzyć konkretne podstrony.

Trasy dynamiczne

Do tej pory określaliśmy dokładną trasę, którą chcieliśmy dopasować. Na przykład trasy „/” i „about”. Jednak React-router-dom pozwala na definiowanie tras dynamicznych. Trasa dynamiczna zawiera część, która może pasować do parametru zapytania. Po dopasowaniu, parametr zapytania jest przekazywany do strony.

Na przykład w trasie nadrzędnej „posts” mamy zagnieżdżoną trasę z dynamiczną częścią określoną jako :id. Ta trasa akceptuje dowolny tekst zamiast :id i ten tekst staje się dostępny dla komponentu Note jako identyfikator.

Budowa paska nawigacyjnego

Używamy komponentów Link zamiast zwykłych znaczników kotwicznych do nawigacji za pomocą React-Router-dom. Dlatego pasek nawigacyjny powinien wyglądać następująco:

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>
  );
}

Dodaj powyższy kod do src/components/NavBar.jsx.

Tworzenie stron

Teraz przejdziemy do tworzenia poszczególnych podstron. W przypadku strony głównej, dodaj następujący kod do src/pages/Home.jsx.

import { useNavigate } from "react-router-dom";

export function Home() {
  const navigate = useNavigate();

  return (
    <div className="home-container">
      <h1>Notatki dla profesjonalistów</h1>
      <div className="home-buttons">
        <button
          onClick={() => {
            navigate("/notes/new");
          }}
          className="button primary"
        >
          Zacznij pisać
        </button>
        <button
          onClick={() => {
            navigate("/notes");
          }}
          className="button secondary"
        >
          Przeglądaj notatki
        </button>
      </div>
    </div>
  );
}

Na stronie głównej chcielibyśmy użyć przycisków do nawigacji. Dlatego wykorzystujemy hook `useNavigate` do programowej nawigacji. Importujemy hook, a następnie wywołujemy go w komponencie Home. Zwracana wartość jest funkcją, która pozwala na nawigację.

Teraz zdefiniujemy stronę „O aplikacji”. Dodaj następujący kod do src/pages/About.jsx.

export function About() {
  return (
    <div>
      <h1>O aplikacji</h1>
      <p>Simple Notes to najlepsza aplikacja do notatek dla profesjonalistów</p>
    </div>
  );
}

Teraz zdefiniujemy stronę z listą notatek.

W tym komponencie musimy również dodać komponent Outlet, który będzie używany do renderowania zagnieżdżonych tras. Z tego powodu nasza strona src/pages/Notes.jsx będzie wyglądać następująco.

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>
  );
}

Teraz definiujemy stronę z pojedynczą notatką.

Będzie ona renderowana dla każdej notatki indywidualnie. Aby wybrać odpowiednią notatkę do wyrenderowania, komponent Note pobierze identyfikator z dynamicznej części trasy. Wykorzystamy do tego hook useParams. Kod w pliku src/pages/Note.jsx powinien wyglądać następująco:

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>
  );
}

Na koniec stworzymy komponent NewNote w pliku src/pages/NewNote.jsx, dodając następujący kod:

export function NewNote() {
  return (
    <div class="new-note-container">
      <form class="new-note-form">
        <h2>Nowa Notatka</h2>
        <input type="text" name="title" placeholder="Tytuł notatki" />
        <textarea rows="10" placeholder="Tekst notatki" />
        <button class="button primary">Zapisz Notatkę</button>
      </form>
    </div>
  );
}

W tym momencie napisaliśmy cały kod naszej aplikacji. Możesz uruchomić aplikację za pomocą polecenia `npm run dev`. Przejdź przez różne podstrony i zobacz, jak szybki jest routing po stronie klienta.

Wady routingu po stronie klienta

Pomimo wielu zalet, routing po stronie klienta ma też swoje wady, które omówiono poniżej:

  • Początkowe ładowanie strony może być wolne, ponieważ konieczne jest załadowanie całej aplikacji. Pakiet JavaScript może być bardzo duży i czas jego załadowania może być długi.
  • Ponieważ znaczniki są generowane przez JavaScript, strona nie będzie tak dobrze zoptymalizowana pod kątem SEO.
  • Ponieważ wszystko zależy od JavaScript, przeglądarki, które nie obsługują JavaScript lub mają go wyłączonego, nie będą mogły uruchomić aplikacji.

Podsumowanie

W tym artykule omówiliśmy routing w React, tworząc prostą aplikację. Chociaż nie poruszyliśmy wszystkich aspektów, w tym tutorialu omówiliśmy koncepcje, które będziesz używać w większości projektów. Więcej informacji na temat pakietu React-Router-dom można znaleźć w oficjalnej dokumentacji.

Następnie zapoznaj się z artykułem o bibliotekach formularzy React.


newsblog.pl