3. Reaktivita v JavaScriptu & Integrace s Reactem
Moderní JavaScript umožňuje vytvářet dynamické a interaktivní webové aplikace, a to především díky funkcím, které podporují reaktivní programování a snadnou manipulaci s uživatelským rozhraním. V této kapitole se zaměříme na principy reaktivity v JavaScriptu a následně si ukážeme, jak je React využívá.
Data binding je proces, díky kterému se změny v datech (např. v proměnné, stavu aplikace atd.) automaticky promítnou do uživatelského rozhraní. V tradičním JavaScriptu se o to vývojář staral ručně, často s využitím knihoven jako jQuery – bylo potřeba aktualizovat DOM přímo (vyhledat element a přepsat mu text, class, apod.).
V moderním pojetí (frameworky typu React, Vue, Angular) je data binding často řešen deklarativně. Vývojář definuje, jak se mají data „propsat“ do šablony, a framework sám zajišťuje, že se při změně stavu tyto informace promítnou do uživatelského rozhraní.
-
Jednocestné vs. dvoucestné:
- Jednocestné (One-way data binding): Data tečou jedním směrem – od stavu aplikace k uživatelskému rozhraní a zpět do stavu (přes definované funkce). Typické pro React.
- Dvoucestné (Two-way data binding): Aktualizace uživatelského rozhraní se automaticky promítne do stavu. Typické pro Angular či Vue (s určitými omezeními/konvencemi).
-
Výhody deklarativního data bindingu:
- Lepší udržovatelnost: Jasně víme, jak se data promítnou do UI, namísto manuální manipulace s DOM.
- Menší riziko chyb: Framework (např. React) zajišťuje synchronizaci stavu a UI za nás.
-
Příklady:
// Tradiční JavaScript const button = document.getElementById('myButton'); button.addEventListener('click', function() { const input = document.getElementById('myInput'); const output = document.getElementById('myOutput'); output.textContent = input.value; // Aktualizace DOM });// React function MyComponent() { const [inputValue, setInputValue] = useState(''); return ( <div> <input type="text" value={inputValue} onChange={(e) => setInputValue(e.target.value)} /> <p>{inputValue}</p> {/* React automaticky aktualizuje UI */} </div> ); }
V reaktivním programování (a v moderních JS knihovnách) se pracuje s událostmi (events) tak, aby komponenty reagovaly na uživatelské interakce (kliknutí, odeslání formuláře, psaní do inputu apod.).
-
Asynchronní povaha: Události jsou zpracovávány asynchronně (tzv. event loop). JavaScript v prohlížeči běží v jednom vlákně, a proto se využívá událostní smyčka (Event Loop) k řízení chování.
-
Callbacky a Event Listenery: Tradičním způsobem je volání funkcí, které reagují na konkrétní akce (např.
document.addEventListener('click', ...)). -
V Reactu: Eventy se řeší přes deklarativní přístup – například
onClickprop v Reactu. To zjednodušuje spojení mezi UI a obchodní logikou. -
Příklady:
// Tradiční JavaScript document.getElementById('myButton').addEventListener('click', function() { alert('Button clicked!'); }); // React function MyComponent() { return <button onClick={() => alert('Button clicked!')}>Click me</button>; }
React používá speciální syntaxi JSX (JavaScript XML), nebo také TSX (TypeScript XML). Jde o syntaktickou nadstavbu JavaScriptu/TypeScriptu, která umožňuje psát kód, jenž vypadá jako HTML, ale je kompilován do klasických volání JavaScript funkcí.
- Deklarativní zápis:
Tento zápis je přeložen do JavaScriptu jako:
const element = <h1>Hello, world!</h1>;const element = React.createElement('h1', null, 'Hello, world!'); - Výhody JSX:
- Snadnější čtení a psaní kódu.
- Možnost kombinovat JavaScript logiku přímo v HTML-like syntaxi.
- Podpora pro komponenty a jejich props.
- React využívá virtuální DOM, což mu umožňuje efektivně porovnávat nový stav uživatelského rozhraní se stavem předchozím a vykreslovat pouze ty části, které se změnily.
-
Změna stavu:
- V Reactu se data ukládají do state (u funkcionálních komponent pomocí hooků, např. useState) nebo do globálního stavu (např. Redux, Context API).
- Při volání funkce pro nastavení stavu (setState, useState) si React „poznačí“, že došlo k aktualizaci, a naplánuje re-render.
-
Re-render:
- React porovná nově vytvořený virtuální DOM s předchozím (tzv. diffing).
- Provede se jenom aktualizace skutečného DOM tam, kde došlo ke změně.
- Výsledkem je dynamický rendering – uživatel vidí v UI jen změněné části, bez nutnosti překreslovat celou stránku.
-
Příklad:
function Counter() { const [count, setCount] = useState(0); return ( <div> <p>You clicked {count} times</p> <button onClick={() => setCount(count + 1)}> Click me </button> </div> ); }- V tomto příkladu se při každém kliknutí na tlačítko aktualizuje stav
count, což způsobí re-render komponenty a zobrazení nového počtu kliknutí.
- V tomto příkladu se při každém kliknutí na tlačítko aktualizuje stav