Průvodce používáním Reag-router-dom

Pro jakoukoli sofistikovanější aplikaci v Reactu je nezbytné ji rozdělit do více sekcí, které uživatel může navštěvovat. Z tohoto důvodu je klíčové implementovat mechanizmus řízení toku mezi těmito sekcemi, takzvaný routing.

Téma routingu se může na první pohled zdát komplexní. Nicméně, tento návod vám poskytne veškeré potřebné základní znalosti. V rámci tohoto tutoriálu sestavíme aplikaci, která využívá tento koncept.

Co je to React Routing (klient-side routing)

React Routing představuje způsob směrování, které se odehrává na straně klienta, v kontextu aplikací vytvořených pomocí React. Routing na straně klienta je alternativou k routingu na straně serveru. Při tradičním server-side routingu, kdykoli se uživatel přesune na jinou stránku, prohlížeč odešle požadavek GET na webový server. Zpracování tohoto požadavku může trvat i několik sekund, než server pošle odpověď.

V případě webových aplikací, kde se uživatelé často pohybují mezi různými částmi, takové zpoždění může značně zhoršit uživatelský zážitek. Zde se nabízí možnost routingu na straně klienta. Namísto poskytování HTML kódu ze serveru aplikace používá JavaScript k dynamickému generování HTML pro jednotlivé stránky.

Pro spuštění aplikace je třeba pouze jediný vstupní bod, kterým je soubor index.html. Tento soubor následně načte JavaScriptový kód aplikace. Tento kód pak vykresluje jednotlivé stránky pomocí manipulace s DOM, řeší routing a zajišťuje celkovou funkcionalitu aplikace.

Protože server poskytuje pouze stránku index.html, tato forma aplikací je často označována jako jednostránková aplikace (SPA).

Výhody routingu na straně klienta

  • Zlepšuje uživatelský komfort díky rychlejší navigaci a celkově svižnějšímu chodu aplikace. Na rozdíl od server-side routingu, kde každá navigace vyžaduje nový síťový požadavek s prodlevou, klient-side routing zajišťuje téměř okamžitou odezvu.
  • Umožňuje tvorbu offline aplikací, protože veškerý kód potřebný ke spuštění aplikace lze uložit do lokální paměti. To umožňuje vytvářet aplikace dostupné i bez internetového připojení, a tím nabízet offline funkce.
  • Aplikace také využívá méně dat, protože celkový počet síťových požadavků je redukován a některé zdroje jsou ukládány do lokální mezipaměti.
  • Snížení zátěže serveru, protože server musí aplikaci vykreslit jen jednou, na rozdíl od server-side routingu, kde server musí generovat obsah pro každý nový požadavek.

Podívejme se nyní na konkrétní implementaci routingu v Reactu.

Jak implementovat React Routing

V tomto tutoriálu vytvoříme jednoduchou aplikaci pro poznámky, která bude obsahovat více stránek. Budeme používat klient-side routing pomocí knihovny React Router DOM, aby uživatel mohl plynule přecházet mezi jednotlivými stránkami. Hlavní důraz bude kladen na samotný routing a nebude se zabývat komplexní funkčností aplikace.

Předpoklady

Pro absolvování tohoto tutoriálu je nezbytná znalost HTML, JavaScriptu a Reactu. Dále je nutné mít nainstalované Node.js a NPM. Obě komponenty se instalují současně s instalací Node.js ze stránek projektu. Další informace jsou k dispozici v přiloženém videu na YouTube.

Co budeme vytvářet

Naše aplikace bude složena z více stránek, mezi kterými se uživatel bude moci pohybovat pomocí react routingu. Níže jsou uvedeny návrhy jednotlivých stránek.

Domovská stránka bude dostupná na adrese ‚/‘.

Stránka O aplikaci na adrese ‚/about‘.

Stránka s poznámkami na adrese ‚/notes‘.

Stránka pro novou poznámku na adrese ‚/notes/new‘.

Plný obsah poznámky bude zobrazen na detailní stránce. Tato stránka bude dostupná na adrese ‚/routes/<id>‘, kde <id> bude číslo odpovídající ID poznámky.

Začínáme

Pro začátek vytvoříme nový React projekt. Já budu používat Vite, proto pro inicializaci nového projektu použiji následující příkaz:

npm create vite@latest scribbble --template react

Jako název projektu jsem zvolil ‚scribbble‘ a jako šablonu React. Následně projekt otevřu v editoru VS Code pomocí příkazů:

cd scribbble
code .

Po otevření projektu v VS Code se vrátím do terminálu a nainstaluji knihovnu react-router-dom. Tato knihovna nám usnadní implementaci routingu v React aplikacích.

npm install react-router-dom

Nyní vytvoříme soubor, ve kterém budou uloženy naše poznámky. Vytvořte soubor src/notes.js a přidejte do něj následující kód:

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

Následně smažte soubor src/App.css. V tomto projektu ho nebudeme potřebovat. Nezapomeňte smazat import tohoto souboru i ze souboru App.jsx.

Poté nahraďte obsah souboru index.css následujícím kódem:

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

Nyní vytvoříme soubory pro stránky, které chceme vytvořit:

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

Nakonec vytvořte soubor pro komponentu Navigační lišta. Tento soubor umístěte do src/components/NavBar.jsx

Nastavení React Routingu

Po vytvoření základní struktury naší aplikace můžeme přistoupit k samotnému nastavení routingu.

Otevřete soubor App.jsx a vymažte z něj veškerý obsah. Následně na začátek souboru přidejte následující 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";

Importujeme komponenty BrowserRouter, Routes a Route z knihovny react-router-dom. Tyto komponenty budou klíčové pro nastavení routeru. Dále importujeme NavBar z našeho adresáře komponent a několik stránek z našich souborů stránek. Tyto stránky sice ještě nejsou implementovány, ale brzy se k tomu dostaneme.

Nyní nastavíme samotnou komponentu aplikace:

export default App () {

  }

Do příkazu return přidáme následující kód:

return (
      <BrowserRouter>
        
      </BrowserRouter>
  )

Tímto způsobem vykreslíme BrowserRouter, komponentu React poskytovanou knihovnou react-router-dom. Tato komponenta konfiguruje router, který běží v rámci prohlížeče. Celá naše aplikace bude obalena těmito značkami.

Nyní přidáme navigační lištu a vytvoříme komponentu Routes.

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

Do prvku BrowserRouter jsme přidali NavBar. Tuto komponentu definujeme později, ale jejím úkolem je vytvářet odkazy v horní části každé stránky. Místo vytváření samostatných navigačních prvků pro každou stránku vytvoříme jeden sdílený NavBar.

Následně jsme vytvořili prvek kontejneru. Tento prvek není pro samotný routing zásadní, ale slouží pro aplikování stylů.

Uvnitř kontejneru jsme přidali komponentu Routes. Zde se budou vykreslovat jednotlivé stránky, podle aktuální adresy v prohlížeči. Veškerý obsah uvnitř komponenty Routes se bude znovu vykreslovat při každé změně adresy.

Nakonec přidáme konkrétní cesty pro jednotlivé stránky.

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

Komponenta Home se vykreslí, pokud cesta bude ‚/‘, komponenta About se vykreslí na cestě ‚/about‘. Komponenta Notes se vykreslí pro cestu ‚/notes‘. Navíc máme také definované cesty ‚/notes/new‘ a ‚/notes/:id‘ jako vnořené trasy.

Vysvětlení vnořených cest

Trasa může obsahovat vnitřní cesty. Tyto trasy se nazývají vnořené trasy. Cesta k těmto vnořeným trasám bude spojena s nadřazenou trasou, a tím vytvoří kompletní cestu. Například trasy „poznámky“ a „nová“ se sloučí do „/poznámky/nová“.

Z hlediska vykreslování komponent, pokud uživatel přejde na nadřazenou trasu, vykreslí se pouze nadřazená komponenta. Nicméně, pokud uživatel přejde na vnořenou trasu, vykreslí se obě, nadřazená i vnořená komponenta.

Pro vykreslení obou komponent je nezbytné, aby komponenta Notes obsahovala komponentu Outlet, která definuje, kde se bude vkládat komponenta Note. Uvidíte to brzy, až budeme tvořit jednotlivé stránky.

Dynamické cesty

Doposud jsme specifikovali přesné cesty, které se mají spárovat. Například cesty ‚/‘ a ‚about‘. Nicméně, react-router-dom nám umožňuje specifikovat i dynamické cesty. Dynamická cesta obsahuje proměnnou část, která může být porovnána s parametrem dotazu. Po nalezení shody je tento parametr předán stránce.

Například, uvnitř rodičovské cesty ‚posts‘ máme vnořenou trasu, která obsahuje dynamickou část určenou pomocí :id. Tato trasa akceptuje jakýkoli text namísto :id a tento text bude dostupný komponentě Note jako id.

Tvorba navigační lišty

Pro navigaci pomocí react-router-dom používáme komponenty Link namísto standardních značek a. Proto by měl náš navigační panel vypadat takto:

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

export function NavBar() {
  return (
    <div className="nav-container">
      <Link to="/">Scribbble</Link>
      <nav className="nav">
        <Link to="/about">O aplikaci</Link>
        <Link to="/notes">Poznámky</Link>
        <Link to="/notes/new">Nová poznámka</Link>
      </nav>
    </div>
  );
}
  

Přidejte tento kód do src/components/NavBar.jsx.

Tvorba jednotlivých stránek

Nyní se pustíme do tvorby samotných stránek. Pro domovskou stránku přidejte následující kód do souboru src/pages/Home.jsx.

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

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

  return (
    <div className="home-container">
      <h1>Poznámky pro profesionály</h1>
      <div className="home-buttons">
        <button
          onClick={() => {
            navigate("/notes/new");
          }}
          className="button primary"
        >
          Začít psát
        </button>
        <button
          onClick={() => {
            navigate("/notes");
          }}
          className="button secondary"
        >
          Zobrazit poznámky
        </button>
      </div>
    </div>
  );
}
  

Na domovské stránce chceme používat tlačítka pro navigaci. Proto použijeme háček useNavigate pro programovou navigaci. Importovali jsme tento háček a zavolali ho uvnitř komponenty Home. Návratovou hodnotou tohoto volání je funkce, kterou můžeme používat pro navigaci.

Nyní definujeme stránku O aplikaci. Přidejte následující kód do souboru src/pages/About.jsx.

export function About() {
  return (
    <div>
      <h1>O aplikaci</h1>
      <p>Simple Notes je nejlepší aplikace pro psaní poznámek pro profesionály</p>
    </div>
  );
}

Nyní definujeme stránku Poznámky.

V této komponentě musíme také zahrnout komponentu Outlet, která se použije pro vykreslení libovolných vnořených tras. Proto by měl kód v src/pages/Notes.jsx vypadat takto.

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

Dále definujeme stránku pro zobrazení jedné poznámky.

Tato stránka se bude zobrazovat pro jednu konkrétní poznámku. Pro zjištění, kterou poznámku zobrazit, budeme z dynamické části URL adresy načítat id. K tomu použijeme háček useParams. Kód v src/pages/Note.jsx by měl být:

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

Nakonec vytvoříme komponentu NewNote v souboru src/pages/NewNote.jsx, takto:

export function NewNote() {
    return (
      <div class="new-note-container">
        <form class="new-note-form">
          <h2>Nová poznámka</h2>
          <input type="text" name="title" placeholder="Název poznámky" />
          <textarea rows="10" placeholder="Text poznámky" />
          <button class="button primary">Uložit poznámku</button>
        </form>
      </div>
    );
  }

V tuto chvíli jsme napsali veškerý potřebný kód pro naši aplikaci. Aplikaci můžete spustit pomocí příkazu npm run dev. Pohybujte se mezi různými stránkami a všímejte si rychlosti, kterou nám klient-side routing nabízí.

Nevýhody routingu na straně klienta

I přes své výhody má klient-side routing i několik nevýhod. Ty jsou popsány níže:

  • První načtení stránky může trvat déle, protože se musí načíst celá aplikace. Velikost javascriptového balíčku může být značná, což prodlužuje čas potřebný pro načtení.
  • Protože HTML kód se generuje dynamicky pomocí JavaScriptu, taková stránka nemusí být optimální pro vyhledávače (SEO).
  • Protože vše závisí na JavaScriptu, prohlížeče, které nepodporují JavaScript nebo mají JavaScript vypnutý, nebudou moci aplikaci spustit.

Závěr

V tomto článku jsme se zabývali routingem v Reactu vytvořením jednoduchého projektu. I když jsme neprošli všechny detaily, tento tutoriál pokryl základní koncepty, které využijete ve většině projektů. Více informací o react-router-dom naleznete na oficiálních stránkách projektu.

Nyní si můžete přečíst další článek o knihovnách pro práci s formuláři v Reactu.