– Nejedná se o vykreslování na straně serveru.
.
Rok 2020 byl pro nás všechny šílenou jízdou. Pro letošní prázdniny na konci roku tým React nedávno oznámil vzrušující výzkum nového způsobu vytváření aplikací React pomocí React Server Components.
Mějte prosím na paměti, že React Server Components je stále ve vývoji a zatím se nedoporučuje pro produkci. Funkce je zcela volitelná a komponenty můžete stále psát jako dnes.
Na hodinovou přednášku a ukázku se můžete podívat zde, ale zde je pětiminutový průvodce, který zdůrazňuje a vysvětluje důležité části.
Pokud vás také zajímá, jakou roli hrají nové komponenty Reactu v budoucích návrhových systémech, doporučuji si přečíst:
React Server Component je způsob, jak napsat komponentu Reactu, která se vykresluje na straně serveru s cílem zlepšit výkon aplikace React.
Jedním z problémů, se kterými se setkáváme při vývoji aplikací s Reactem, je běžný vysoký počet síťových požadavků, které jsou prováděny, zatímco uživatelé čekají, až bude požadovaná stránka/data k dispozici:
Například dnes běžný přístup k získávání dat spočívá ve volání rozhraní API pomocí háčku useEffect
:
useEffect(() => {
axios.get("URL HERE")
.then((response) => {
// set data into state setData(response.data);
})
.catch((error) => {
console.log(error);
});
}, );
Ačkoli na tom není nic špatného, tento přístup k získávání dat bude vždy stát nějaký čas, než se uživateli vykreslí něco smysluplného.
Dalším problémem je samozřejmě velikost svazku. Minifikace, rozdělení kódu, eliminace mrtvého kódu je několik příkladů metod používaných ke snížení velikosti svazku aplikace React. Proč? Protože velká velikost svazku vyžaduje čas na stažení. Ne každý má přístup k rychlému zařízení a rychlému internetu:
React Server Components pomůže vyřešit oba výše uvedené problémy a mnoho dalších.
Jak React Server Components funguje
Protože React Server Components je stále v experimentální fázi, mohou se detaily implementace této funkce změnit. I tak si ale můžete některé její základní koncepty osvojit, když se podíváte na ukázku.
V první řadě si všimněte, že v souboru package.json
je několik balíčků s experimentální verzí:
"react": "0.0.0-experimental-3310209d0",
"react-dom": "0.0.0-experimental-3310209d0",
"react-fetch": "0.0.0-experimental-3310209d0",
"react-fs": "0.0.0-experimental-3310209d0",
"react-pg": "0.0.0-experimental-3310209d0",
"react-server-dom-webpack": "0.0.0-experimental-3310209d0",
Pakety react
, react-dom
a react-server-dom-webpack
používají experimentální verzi, která umožňuje použití komponenty React Server, zatímco react-fetch
, react-fs
a react-pg
je skupina obalových balíčků používaných pro interakci se vstupním/výstupním systémem (Nazývají se React IO Libraries)
Dalším bodem je, že toto demo je poháněno Expressem.js, což dává smysl, protože k vykreslování komponent potřebujete server. To však také vyvolává otázku: Znamená to, že serverové komponenty fungují pouze v prostředí JavaScriptu? Co třeba Go, Java a další prostředí na straně serveru?“
V budoucnu se možná dočkáme podpory dalších prostředí, takže tento bod prozatím ponechme stranou.
Všechny tyto implementační detaily se samozřejmě mohou v budoucnu změnit, jak bude postupovat výzkum.
Přejdeme-li ke kódu uvnitř složky src/
, můžeme vidět tři druhy rozšíření pro soubory komponent:
-
.server.js
rozšíření označuje serverové komponenty -
.client.js
rozšíření označuje klientské komponenty React - Obvyklé rozšíření
.js
je určeno pro sdílené komponenty. Tyto komponenty mohou být spuštěny na serveru nebo na klientovi, podle toho, kdo je importuje.
Při spuštění aplikace příkazem npm start
se současně spustí dvě úlohy:
- Server Node spuštěný pomocí skriptu
server/api.server.js
- Sestavení Webpack pro balíček React na straně klienta pomocí skriptu
scripts/build.js
Při pohledu na serverový skript je vidět, že se do souboru importuje app.server.js
:
const ReactApp = require('../src/App.server').default;
A později se zpracuje jako Node Writable stream:
const {pipeToNodeWritable} = require('react-server-dom-webpack/writer');async function renderReactTree(res, props) {
await waitForWebpack();
const manifest = readFileSync(
path.resolve(__dirname, '../build/react-client-manifest.json'),
'utf8'
);
const moduleMap = JSON.parse(manifest);
pipeToNodeWritable(React.createElement(ReactApp, props), res, moduleMap);
}
Kód pod příponou .server.js
včetně jeho závislostí není zahrnut do klientského svazku, což znamená, že má nulový vliv na velikost svazku.
Serverové komponenty mají přímý přístup k databázi nebo souborovému systému na serveru, takže můžete vyzvednout jakákoli potřebná data a poslat je klientovi při prvním vykreslení. Příklad můžete vidět v souboru NoteList.server.js
:
export default function NoteList({searchText}) {const notes = db.query(
`select * from notes where title ilike order by id desc`,
).rows;
return notes.length > 0 ? (
<ul className="notes-list">
{notes.map((note) => (
<li key={note.id}>
<SidebarNote note={note} />
</li>
))}
</ul>
) : (
<div className="notes-empty">
{searchText
? `Couldn't find any notes titled "${searchText}".`
: 'No notes created yet!'}{' '}
</div>
);
}
Serverové komponenty nemohou mít žádnou interaktivitu, což znamená, že nemůžete useState
ani vytvářet posluchače na straně serveru. Musíte do nich vložit stav na straně klienta a importovat je ze serverových komponent.
Jaký je přínos React Server Component?
- Serverové komponenty nejsou součástí balíčku. Prohlížeč je nikdy nestahuje, což má nulový vliv na velikost svazku
- Velikost svazku můžete snížit přesunutím statických komponent určených pouze k vykreslování na stranu serveru a ponecháním interaktivních-statečných komponent na straně klienta
- Serverové komponenty mohou přistupovat ke zdrojům na straně serveru. Můžete přímo načítat data z databáze nebo souborového systému a můžete také načítat data z rozhraní API stejně jako na straně klienta
- Serverové komponenty mohou také číst dotazy GraphQL
Jak se to liší od vykreslování na straně serveru?“
SSR tak, jak funguje dnes v aplikacích React, jednoduše posílá komponenty vykreslené jako HTML do klienta, aby vaše aplikace vypadala, že má rychlou odezvu. Uživatel nemůže s vaší aplikací nic dělat, dokud se nestáhne JavaScript.
React Server Components je jiný. Jak ukazuje ukázka, komponenty serveru nejsou vykreslovány jako HTML, ale jako speciální formát, který je streamován do klienta. Tento stream zatím nemá žádný standardní protokol, ale hodně se podobá formátu JSON. Zde je kousek odpovědi:
M1:{"id":"./src/SearchField.client.js","chunks":,"name":""}
Když se SSR použije pouze jednou pro počáteční vykreslení, Server Components lze opakovaně načíst a znovu vykreslit data (v případě ukázky příspěvky markdown).
Závěr
React Server Components je nová zajímavá funkce, která může změnit způsob, jakým vývojáři píší své aplikace React. Umožňuje aplikacím React importovat balíčky bez dopadu na velikost klientského balíčku a vytvářet statickou reprezentaci aplikace, která může být interaktivní pomocí Client Components.
Vývojáři také mohou používat Server Components i Client Components v rámci jednoho stromu DOM, což umožňuje opětovné načítání serverových komponent bez zničení stavu klientských komponent.
Protože je však tato funkce stále experimentální, je těžké určit, jak bude skutečně užitečná v praxi. Jednak tuto funkci lze v současné době používat pouze v prostředí serveru Node.js.
Tým Reactu se v současné době soustředí na zavedení této funkce do meta-frameworků jako Next.js a Gatbsy, což znamená, že může nějakou dobu trvat (pokud vůbec), než se dočkáme podpory dalších jazyků na straně serveru, jako je PHP, Python, Go nebo Ruby.
Abychom to shrnuli, React na straně klienta nezmizí. React na straně serveru je volitelný.
Také jsem se podělil o své myšlenky na téma Should you create a design system for React Server Components? které by vás mohly zajímat.