Водич за коришћење реацт-роутер-дом

За све сложеније React апликације, неопходно је разложити их на више засебних страница. Како би се то постигло, имплементација рутирања постаје суштинска.

У почетку, ово може изгледати као застрашујућа тема. Међутим, овај водич ће вам пружити све неопходне основе. У оквиру овог упутства, креираћемо апликацију која користи рутирање.

Шта је React рутирање (рутирање на страни клијента)?

React рутирање представља форму рутирања на страни клијента која је интегрисана у React апликације. Рутирање на страни клијента је алтернатива рутирању на страни сервера. Код рутирања на страни сервера, прегледач упућује GET захтев веб серверу сваки пут када се навигујете на другу страницу. Овај захтев може потрајати неколико секунди док не добијете одговор.

За веб апликације где се стално прелази са једне странице на другу, време чекања негативно утиче на корисничко искуство. Рутирање на страни клијента представља алтернативно решење. Уместо да сервер шаље HTML прегледачу, апликација користи JavaScript за генерисање HTML-а за различите странице.

Довољно је да наведете `index.html` датотеку као улазну тачку како би апликација радила. Ова улазна тачка потом учитава ваш JavaScript код. JavaScript пакет затим приказује странице манипулацијом DOM-ом, управљањем рутирањем и применом функционалности апликације.

Будући да сервер сервира само `index.html` страницу, апликација се назива апликација са једном страницом.

Предности рутирања на страни клијента

  • Омогућава боље корисничко искуство, јер је навигација бржа и апликација боље реагује. Код рутирања на страни сервера, свака навигација подразумева мрежни захтев са кашњењем од неколико секунди.
  • Омогућава креирање офлајн апликација, јер се сав код потребан за покретање апликације може локално кеширати. Ово вам омогућава да направите приступачније апликације и понудите функционалности ван мреже.
  • Апликација ће такође користити мање података, јер се мрежни захтеви знатно смањују ако се све пошаље једном, а неке датотеке кеширају локално.
  • Такође смањује оптерећење сервера, јер сервер треба само једном да прикаже апликацију. Ово је супротно рутирању на страни сервера, где сервер непрекидно приказује апликацију.

Даље, размотрићемо како се имплементира React рутирање.

Како имплементирати React рутирање

За потребе овог водича, направићемо једноставну апликацију за вођење белешки. Она ће се састојати од више страница. Имплементираћемо рутирање на страни клијента користећи React Router DOM, како би омогућили кориснику да се лако креће између различитих страница. Нећемо се фокусирати на комплетну функционалност апликације, већ ћемо се концентрисати на сам процес рутирања.

Предуслови

Да бисте успешно пратили овај водич, неопходно је разумевање HTML-а, JavaScript-а и React-а. Такође, морате имати инсталиран Node.js и NPM. Можете их преузети и инсталирати заједно преко званичне веб странице или пратећи упутства у приложеном YouTube видео-запису.

Шта ћемо направити

Апликација ће имати више различитих страница. Користећи React рутирање, биће омогућена навигација до различитих страница. Дизајн страница је приказан у наставку.

Почетна страница се приказује на `/` рути.

Страница „О нама“ се приказује на `/about` рути.

Страница за белешке се приказује на `/notes` рути.

Страница за креирање нове белешке се приказује на `/notes/new` рути.

Свака белешка се може у целости погледати на засебној страници. Ова страница се приказује на рути `/notes/:id`, где је `:id` цео број који представља јединствени идентификатор белешке коју желимо да прочитамо.

Почетак

За почетак, креирајте нови React пројекат. Ја ћу користити Vite, тако да је команда за иницијализацију новог пројекта следећа:

npm create vite@latest scribbble --template react

Навео сам ‘scribbble’ као име пројекта и React као шаблон. Затим ћу отворити VS Code користећи следеће команде:

cd scribbble
code .

Након што се VS Code отвори, вратићу се у терминал и инсталирати `react-router-dom`. Овај пакет олакшава имплементацију React рутирања у ваше апликације.

npm install react-router-dom

Сада ћемо креирати датотеку у којој ће бити ускладиштене наше белешке. Направите датотеку `src/notes.js` и додајте следећи код:

const notes = [
  {
    id: 1,
    title: "Белешка 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: "Белешка 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: "Белешка 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;

Затим, обришите датотеку `src/App.css`. Нећемо је користити у овом пројекту. Такође, уклоните увоз за `App.css` датотеку из `App.jsx` датотеке.

Након тога, замените цео садржај у датотеци `index.css` следећим:

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

Затим, креирајте следеће датотеке за странице које ћемо направити:

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

На крају, креирајте датотеку за компоненту навигационе траке. Ова датотека ће бити смештена у `src/components/NavBar.jsx`.

Подешавање React рутирања

Када је наша апликација припремљена, можемо подесити рутирање у оквиру апликације.

Отворите датотеку `App.jsx` и обришите сав њен садржај. Затим додајте следеће увозе на врх датотеке:

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

Увозимо компоненте `BrowserRouter`, `Routes` и `Route` из пакета `react-router-dom`. Они ће се користити за подешавање рутера. Затим смо увезли `NavBar` из директоријума са компонентама и неколико страница из датотека страница. Странице још нисмо имплементирали, али ћемо то учинити ускоро.

Сада ћемо подесити нашу апликациону компоненту:

export default function App() {

}

Затим додајемо следеће ознаке у нашу повратну изјаву:

return (
    <BrowserRouter>
      
    </BrowserRouter>
)

Ово приказује `BrowserRouter`, React компоненту која долази из пакета `react-router-dom`. Ова компонента конфигурише рутер који ради унутар прегледача. Наша апликација ће бити садржана унутар ових ознака.

Затим додајемо навигациону траку и креирамо `Route` компоненту.

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

Унутар елемента `BrowserRouter` додали смо `NavBar`. Касније ћемо дефинисати овај елемент, али он служи за стварање веза на врху сваке странице. Уместо да га пишемо посебно за сваку страницу, направићемо један `NavBar`.

Затим смо креирали елемент контејнера. Овај елемент није неопходан за рутирање, већ је ту ради стилизације.

Унутар контејнера смо додали компоненту `Routes`. Овде ће се приказивати различите странице, у зависности од руте у којој се прегледач налази. Све што је унутар компоненте `Routes` биће поново приказано сваки пут када се рута промени.

На крају, додајемо руте за различите странице.

  return (
    <BrowserRouter>
      <NavBar />
      <div className="container">
        <Routes>
          <Route path="/" element={} />
          <Route path="about" element={} />
          <Route path="notes" element={}>
            <Route path="new" element={} />
            <Route path=":id" element={} />
          </Route>
        </Routes>
      </div>
    </BrowserRouter>
  );

Компонента `Home` ће бити приказана када је путања `/`, а компонента `About` ће бити приказана на рути `/about`. Компонента `Notes` ће бити приказана на рути `/notes`. Такође имамо `/notes/new` руту и `/notes/:id` дефинисане као угнежђене руте.

Објашњење угнежђених рута

Рута може садржати унутрашње руте. Оне се називају угнежђене руте. Путања до ових угнежђених рута се спаја са родитељском рутом како би се формирала цела путања. На пример, руте `notes` и `new` ће бити комбиноване у `/notes/new`.

Што се тиче приказа компоненти када корисник приступи надређеној рути, биће приказана само надређена компонента. Међутим, и родитељска и угнежђена компонента ће бити приказане заједно када се навигује по угнежђеној рути.

Да би се обе компоненте приказале заједно, компонента `Notes` мора да прикаже компоненту `Outlet`, која одређује где ће компонента `Note` бити уграђена. Видећете ово касније када почнемо да правимо странице.

Динамичке руте

До сада смо специфицирали дословну руту коју желимо да ускладимо. На пример, руте `/` и `/about`. Међутим, `react-router-dom` нам омогућава да специфицирамо динамичке руте. Динамичка рута садржи део који се може упарити са параметром упита. Када се подударање оствари, параметар упита се прослеђује на страницу.

На пример, унутар родитељске руте `posts`, имамо угнежђену руту која садржи динамички део специфициран са `:id`. Ова рута прихвата било који текст уместо `:id` и тај текст постаје доступан компоненти `Note` као `id`.

Прављење навигационе траке

Користићемо `Link` компоненте уместо стандардних сидришта за навигацију уз помоћ пакета `react-router-dom`. Дакле, наша навигациона трака би требало да изгледа овако:

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

export function NavBar() {
  return (
    <div className="nav-container">
      <Link to="/">Scribbble</Link>
      <nav className="nav">
        <Link to="/about">О нама</Link>
        <Link to="/notes">Белешке</Link>
        <Link to="/notes/new">Нова белешка</Link>
      </nav>
    </div>
  );
}

Додајте овај код у датотеку `src/components/NavBar.jsx`.

Израда страница

Затим ћемо направити странице. За почетну страницу, додајте следећи код у `src/pages/Home.jsx`:

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

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

  return (
    <div className="home-container">
      <h1>Белешке за професионалце</h1>
      <div className="home-buttons">
        <button
          onClick={() => {
            navigate("/notes/new");
          }}
          className="button primary"
        >
          Започни са писањем
        </button>
        <button
          onClick={() => {
            navigate("/notes");
          }}
          className="button secondary"
        >
          Погледај белешке
        </button>
      </div>
    </div>
  );
}

На почетној страници желимо да користимо дугмад за навигацију. Због тога користимо хук `useNavigate` за програмску навигацију. Увезли смо хук и позвали га унутар компоненте `Home`. Повратна вредност након позивања хука је функција коју можете користити за навигацију.

Затим ћемо дефинисати страницу `About`. Додајте следећи код у датотеку `src/pages/About.jsx`:

export function About() {
  return (
    <div>
      <h1>О нама</h1>
      <p>Simple Notes је најбоља апликација за белешке за професионалце</p>
    </div>
  );
}

Након тога, дефинисаћемо страницу `Notes`.

У ову компоненту, такође морамо укључити компоненту `Outlet` која ће се користити за приказ свих угнежђених рута. Из тог разлога, наша страница `src/pages/Notes.jsx` ће изгледати овако:

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

Затим, дефинишемо страницу за једну белешку.

Ово ће бити приказано за појединачну белешку. Да би се одредила белешка за приказ, `Note` ће приступити ID-у наведеном у динамичком делу руте. Да бисмо то урадили, користимо хук `useParams`. Према томе, ово би требало да буде код у вашој датотеци `src/pages/Note.jsx`:

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

На крају, креираћемо компоненту `NewNote` унутар датотеке `src/pages/NewNote.jsx` користећи следећи код:

export function NewNote() {
  return (
    <div class="new-note-container">
      <form class="new-note-form">
        <h2>Нова белешка</h2>
        <input type="text" name="title" placeholder="Наслов белешке" />
        <textarea rows="10" placeholder="Текст белешке" />
        <button class="button primary">Сачувај белешку</button>
      </form>
    </div>
  );
}

У овом тренутку смо написали сав код за апликацију. Можете покренути апликацију користећи `npm run dev`. Прелазите на различите странице и уверите се колико је брзо рутирање на страни клијента.

Недостаци рутирања на страни клијента

Упркос бројним предностима, рутирање на страни клијента има и неке недостатке. Они су објашњени у наставку:

  • Почетно учитавање странице може бити споро, јер се цела апликација мора учитати. JavaScript пакет може бити веома велик и захтева дуже време учитавања.
  • Будући да JavaScript генерише ознаке, страница неће бити оптимизована за SEO.
  • Будући да све зависи од JavaScript-а, прегледачи који не подржавају JavaScript или имају JavaScript онемогућен неће моћи да покрену апликацију.

Закључак

У овом чланку смо покрили React рутирање тако што смо направили мали пројекат. Иако нисмо обухватили све, овај водич покрива концепте које ћете користити у већини пројеката на којима ћете радити. За више информација о `react-router-dom`, погледајте званичну документацију.

Даље, прочитајте овај чланак о React библиотекама за обрасце.