Lekce 3 - Serverové renderování s Next.js
V předchozí lekci, Vykreslování v Reactu a jeho optimalizace, jsme se seznámili s tím, jak v Reactu probíhá vykreslování. Popsali jsme si stručně některé z možností další optimalizace, konkrétně memoizaci, lazy loading a virtualizaci.
V dnešním tutoriálu pokročilého Reactu se budeme zabývat tématem, které se stává stále populárnějším ve světě webových technologií - frameworkem Next.js a serverovým renderováním (Server Side Rendering, zkráceně SSR). Při vývoji komplikovanějších webových aplikací, u nichž je potřeba data zpracovat ještě před tím, než se odešlou klientovi, se totiž bez této techniky neobejdeme.
Co je Next.js?
Next.js je moderní React framework pro vývoj webových aplikací. Je to velmi silný nástroj, který nabízí jak serverové renderování, tak i statické stránkování. Framework je optimalizovaný pro maximální rychlost a bezpečnost, a to zároveň s minimálním konfiguračním úsilím. Nyní se podívejme, jak s Next.js začít.
Abychom mohli Next.js používat, potřebujeme Node.js na verzi alespoň 16.8.x. Ohledně operačních systémů si nemusíme dělat starosti. Next.js nabízí plnou podporu pro Windows, macOS a Linux, ať už pro samostatnou distribuci, či WSL.
Vytvoření Next.js projektu
Nový projekt vytvoříme jednoduše pomocí následujících příkazů.
Verzovací tag @latest
zajistí, že si nainstalujeme nejnovější
verzi. Použití příkazů v takovéto formě nám zároveň stáhne i React a
všechny potřebné závislosti:
Vytvoření Next.js projektu: npx create-next-app@latest moje-aplikace cd moje-aplikace npm run dev
Během tvorby nového projektu budeme v dialogu dotázáni na řadu
parametrů, typicky zdali chceme používat JavaScript nebo TypeScript,
původní lokalizovaný src/
adresář, CSS preprocesor atd.
Protože tvoříme pouze malý projekt, u nějž neoceníme typovou kontrolu,
vystačíme si s JavaScriptem. Tailwind na škodu určitě nebude a úpravu
formátování přes ESLint určitě také oceníme. Nativní směrování
Next.js jistě také využijeme, jak si za chvíli ukážeme, a importování
ponecháme původní. Projekt jsme si tedy nakonfigurovali následujícím
způsobem:
Vytvoření Next.js projektu:
What is your project named? moje-aplikace
Would you like to use TypeScript with this project? No
Would you like to use ESLint with this project? Yes
Would you like to use Tailwind CSS with this project? Yes
Would you like to use `src/` directory with this project? Yes
Use App Router (recommended)? Yes
Would you like to customize the default import alias? No
Tímto jsme vytvořili nový Next.js projekt s názvem
moje-aplikace
a spustili vývojový server. Otevřeme webový
prohlížeč a zadáme adresu http://localhost:3000/
. Uvítací
stránka Next.js bude vypadat podobně jako na následujícím obrázku:

Serverové renderování pomocí Next.js
Když už máme připravený projekt, začneme se základy serverového
renderování. Next.js poskytuje funkci getServerSideProps()
,
kterou použijeme k načítání dat na serverové straně. Tato funkce se
spustí při každém požadavku a vrátí props
(vlastnosti),
které se pak předají naší React komponentě. To tedy znamená, že vše, co
si ve funkci dále definujeme, bude vyvoláno na serveru a ne ve webovém
prohlížeči koncového klienta.
Představme si, že chceme v naší aplikaci zobrazit informace o filmových
postavách ze Star Wars. Protože kdo by nechtěl, aby jeho webová aplikace
fungovala jako plnohodnotná Star Wars encyklopedie? Veškeré tyto informace
nemusíme sami manuálně dohledávat, jednoduše je získáme z veřejného API
na adrese https://swapi.dev/
.
Pokud ještě ve složce src/
nevidíme podsložku
pages/
, vytvoříme si jí. Router Next.js ve výchozím nastavení
totiž automaticky generuje všechny nové stránky z JavaScriptových souborů
uložených ve složce /src/pages/
. Pro nás to má výhodu v tom,
že nemusíme nic dalšího manuálně konfigurovat. Dále si vytvoříme naší
vlastní komponentu, která nám postavy ze Star Wars vyrenderuje. Tu potom
implementujeme do nové stránky jako celek. Budeme tak ctít ideologii Reactu,
v níž by každá část kódu plnící speciální funkci měla být
separována do své vlastní, opakovaně použitelné
komponenty.
Tvorba nové komponenty
Characters
Nejprve uvnitř složky src/
vytvoříme novou složku
components/
. Do ní budeme umisťovat všechny naše komponenty.
Poté uvnitř této složky vytvoříme nový soubor
Characters.js
.
Do souboru Characters.js
si naimportujeme knihovnu Reactu:
import React from 'react';
Dále si vytvoříme komponentu Characters
jako funkci. Tato
funkce přijímá objekt characters
jako prop
a vrací
JSX kód, který zobrazuje informace o každé postavě ze Star Wars. Každá
postava je zobrazena ve svém vlastním <div>
elementu s
názvem postavy jako nadpisem a popisem jako odstavcem. Závorky {}
se používají pro vyvolání JavaScriptu přímo v HTML kódu (jedná se o
syntaxi JSX). Takto můžeme přímo v HTML tagu přistupovat k jednotlivým
hodnotám z objektu characters
v každé iteraci:
function Characters({ characters }) { return ( <div> <h1>Postavy ze Star Wars</h1> {characters.map((character) => ( <div key={character.name}> <h2>{character.name}</h2> <p>This character is {character.height} centimeters tall, weighs {character.mass} kilos and has {character.skin_color} skin color.</p> </div> ))} </div> ); }
V popisu má každá postava uvedeno, kolik váží, jak je vysoká a jaký má tón pleti. Toto všechno jsme zjistili z API Swapi, jehož endpoint si můžeme sami prohlédnout zde. Protože jsou data ze Swapi v angličtině, ilustrativně jsme celý popis ponechali ve stejném jazyce.
Kód jsme nepsali pro každou postavu zvlášť, ale využili jsme funkci
map()
. Tato funkce nám umožňuje vrátit každý prvek z pole
postav, to tedy znamená, že pro každou postavu bude vytvořen nový tag
<div>
.
Nakonec exportujeme naši komponentu Characters
jako výchozí
export:
export default Characters;
Nyní je z Characters
kompletní a opakovaně použitelná
komponenta. V následujících kapitolách ji importujeme do stránky
/postavy
, což bude další stránka naší webové aplikace, na
níž uživatel nalezne seznam postav ze Star Wars.
Implementace stránky
/postavy
V naší podsložce pages/
vytvoříme nový soubor
postavy.js
a vložíme do něj následující kód. Nejdříve si
naimportujeme knihovnu Reactu a také komponentu Characters
:
import React from 'react'; import Characters from '../components/Characters';
Tento kód importuje knihovnu React do našeho souboru. React je knihovna pro
vývoj uživatelských rozhraní, kterou budeme používat pro vytváření
naší stránky s postavami. Zajistí nám také, že budeme moci jednoduše
použít komponentu Characters
.
Tvorba funkce
CharactersPage()
Vytvoříme si novou funkci CharactersPage()
, kterou budeme
následně exportovat. Jedná se o funkci generující celou novou stránku
postavy
. Implementujeme do ní komponentu Characters
následujícím způsobem:
function CharactersPage({ characters }) { return <Characters characters={characters} /> }
Ve funkci CharactersPage()
jsme použili komponentu
Characters
a přiřadili jsme jí parametr characters
,
což je vstupní objekt s postavami ze Star Wars. Je ukrytý ve stejnojmenné
výstupní proměnné z funkce getServerSideProps()
, jejíž
definici provedeme následovně.
Definice funkce
getServerSideProps()
:
Funkce getServerSideProps()
je speciální funkce v Next.js,
která se spustí na serveru před vykreslením stránky. Definujeme si ji
takto:
export async function getServerSideProps() { const res = await fetch('https://swapi.dev/api/people/'); const data = await res.json(); return { props: { characters: data.results, }, }; }
Tato funkce získává data pro naši stránku. V našem případě funkce
stahuje seznam postav ze Star Wars z API na již zmíněné adrese. Výsledkem
této funkce je objekt s vlastností props
, který obsahuje naše
postavy. Tyto postavy jsou pak předány do naší komponenty
Characters
jako prop
. V komponentě
Characters
definované výše pak přistupujeme k jednotlivým
vlastnostem každé postavy.
Zajímavá je funkce fetch()
, kterou jsme použili pro
načítání dat. Tato funkce je standardní součástí moderních webových
prohlížečů a umožňuje nám vykonat HTTP požadavek. V našem případě
jsme ji použili pro načtení dat z API Star Wars. Důležité je si uvědomit,
že fetch je asynchronní operace, což znamená, že může
trvat nějaký čas, než se data načtou. Proto musíme použít klíčové
slovo await
, které nám umožní počkat, až se data načtou,
než s nimi budeme dále pracovat.
Ve funkci getServerSideProps()
jsme také použili klíčové
slovo async
, což nám umožňuje používat await
uvnitř funkce.
Export komponenty
CharactersPage
Nakonec exportujeme naši komponentu CharactersPage opět jako výchozí export:
export default CharactersPage;
V Reactu platí pravidlo, že komponentou je technicky vše.
Routování v Next.js nám však automatizovaným způsobem umožňuje, že
veškeré komponenty vytvořené v adresáři pages/
jsou
považovány za stránky. Díky tomu vygeneruje Next.js
stránku pro každý specifický soubor ve zmíněném adresáři. Takto jsme
komponentu CharactersPage
použili i my. Implementovali jsme do ní
komponentu Characters
, která slouží čistě pro vykreslení
seznamu s postavami.
Nyní máme API úspěšně implementováno a generování jeho obsahu na
stránce /postavy
úspěšně dokončeno. Ověříme si to
zadáním URL stránky manuálně - http://localhost:3000/postavy
.
Uvidíme pak následující výstup:

Soubory s kódem jsou k dispozici v archivu pod lekcí.
V následující lekci, Serverové renderování podruhé - Stylování v Tailwind CSS, dokončíme téma serverového renderování a naši aplikaci nastylujeme pomocí Tailwind CSS.
Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.
Stáhnout
Stažením následujícího souboru souhlasíš s licenčními podmínkami
Staženo 30x (1.48 kB)
Aplikace je včetně zdrojových kódů v jazyce JavaScript