-
Notifications
You must be signed in to change notification settings - Fork 38
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #651 from Czechitas-podklady-WEB/647-update-lekce-…
…react-1 Update lekce React 1
- Loading branch information
Showing
42 changed files
with
586 additions
and
406 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
## Cvičení: Dynamické stránky | ||
|
||
::exc[cvlekce/parametry] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
## Cvičný projekt | ||
|
||
::exc[cvdoma/filmovy-magazin] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
## Cvičení: React Router | ||
|
||
::exc[cvlekce/detsky-koutek] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
--- | ||
title: Filmový magazín | ||
demand: 3 | ||
--- | ||
|
||
Cílem projektu je naprogramovat stránku internetového filmového magazínu. Naše aplikace bude mít menu, ve kterém půjde přepínat mezi několika stránkami. Na jedné stránce bude dále možné vybírat ze seznamu filmy a zobrazit si o nich podrobnosti. | ||
|
||
Známým postupem si vytvořte kopii [repozitáře projektu](https://github.com/Czechitas-podklady-WEB/projekt-filmovy-magazin). Podrobný popis úkolu včetně schéma celé aplikace najdete v popisu repozitáře. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
--- | ||
title: Dětský koutek | ||
demand: 3 | ||
--- | ||
|
||
V tomto cvičení vytvoříte jednoduchou stránku pro dětský koutek. Pomocí knihovny React Router vytvoříte navigaci, která umožní zobrazit různé komponenty na základě cesty v URL. | ||
|
||
1. Vygenerujte si novou aplikaci pomocí příkazu | ||
```sh | ||
npm init kodim-app@latest detsky-koutek | ||
``` | ||
1. Nainstalujte si knihovnu React Router pomocí _npm_: | ||
```sh | ||
npm install react-router-dom | ||
``` | ||
1. Spusťte aplikaci příkazem `npm start` a zkontrolujte, že vám v prohlížeči správně běží. | ||
1. Nebojte se v následujících krocích inspirovat dokumentací [React Routeru](https://reactrouter.com/en/main/start/overview)! | ||
1. V hlavním souboru `index.jsx` založte objekt s routami. Zatím zobrazujte pouze hlavní komponentu `App` pod cestou `/`. Nezapomeňte použít `RouterProvider` ve funkci `render`. Vyzkoušejte, že takto vaše aplikace funguje. | ||
1. V `src` adresáři vytvořte složku `pages` a uvnitř složky s komponentami pro jednotlivé stránky _Home_, _About_ a _Contact_. | ||
1. Stránka _Home_ bude obsahovat nadpis a odstavec s textem: | ||
|
||
``` | ||
Dětský koutek | ||
Vítejte v našem dětském koutku! Jsme místo plné zábavy a dobrodružství pro všechny děti do 6ti let. Najdete u nás hry, aktivity, kvízy a mnoho dalšího, co zabaví vaše ratolesti a pomůže jim učit se nové věci. Vyberte si některou z našich poboček a začněte objevovat svět plný překvapení! | ||
``` | ||
|
||
1. Stránka _About_ bude obsahovat nadpis a odstavec s textem: | ||
|
||
``` | ||
O nás | ||
Jsme tým mladých nadšenců do vzdělávání a zábavy pro děti. Naše poslání je vytvářet podnětné a zábavné aktivity pro děti, které podporují jejich rozvoj a učení nových dovedností. Vytvořili jsme dětský koutek jako místo, kde se děti cítí v bezpečí, mohou objevovat a zároveň se něco nového naučit. Doufáme, že se k nám vydáte a budete s námi sdílet své zážitky a nápady na další aktivity! | ||
``` | ||
|
||
1. Stránka _Contact_ bude obsahovat nadpis a odstavec s textem: | ||
|
||
``` | ||
O nás | ||
Pokud máte jakékoliv otázky, nápady nebo nám chcete prostě jen napsat, zanechte nám zprávu přes náš kontaktní formulář a my se vám co nejdříve ozveme. Pokud preferujete jiný způsob komunikace, můžete nám také napsat e-mail na adresu [email protected] nebo nás kontaktovat přes naše sociální sítě. Děkujeme vám za vaši zpětnou vazbu a těšíme se na vaše zprávy! | ||
``` | ||
|
||
1. V souboru `index.jsx` si naimportujte všechny vytvořené stránky a přidejte je jako `children` vašeho routeru pod cesty `/`, `about` a `contact`. | ||
1. V komponentě `App` vytvořte navigaci pomocí `Link` komponent a dejte do ní odkazy na všechny výše uvedené stránky. Použijte komponentu `Outlet` na vyznačení místa, kam se máji vkládat jednotlivé stránky. | ||
1. Vyzkoušejte, že aplikace správně naviguje - mění adresu a obsah podle klikání na odkazy. | ||
1. Pokud máte čas a chuť, přidejte na web zajímavější obsah dle libosti a nastylujte jednotlivé stránky i navigaci. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
const centers = [ | ||
{ | ||
id: 'hernicka-narodni', | ||
name: 'Hernička v Národní', | ||
address: 'Národní 28, 110 00 Praha 1', | ||
capacity: 20, | ||
open: { | ||
mon: '8:00 - 18:00', | ||
tue: '8:00 - 18:00', | ||
wed: '8:00 - 18:00', | ||
thu: '8:00 - 18:00', | ||
fri: '8:00 - 18:00', | ||
sat: '9:00 - 12:00', | ||
sun: null, | ||
}, | ||
info: 'Nachází se v těsné blízkosti historického centra Prahy a má skvělou polohu pro rodiny které chtějí prozkoumat město a zároveň se postarat o své malé děti. Koutek má příjemné prostředí, kde se děti mohou hrát a učit se novým věcem. K dispozici jsou také kreativní workshopy, kde děti mohou tvořit a vyrábět své vlastní hračky.', | ||
}, | ||
{ | ||
id: 'vodickuv-koutek', | ||
name: 'Vodičkův koutek', | ||
address: 'Vodičkova 39, 110 00 Praha 1', | ||
capacity: 15, | ||
open: { | ||
mon: '9:00 - 17:00', | ||
tue: '9:00 - 17:00', | ||
wed: '9:00 - 17:00', | ||
thu: '9:00 - 17:00', | ||
fri: '9:00 - 17:00', | ||
sat: null, | ||
sun: null, | ||
}, | ||
info: 'Tento koutek je ideálním místem pro rodiče, kteří se chtějí zastavit na nákup v centru Prahy, ale mají s sebou děti. Koutek nabízí profesionální péči o děti, takže se mohou rodiče soustředit na své nákupy a mít klid v duši, že jsou jejich děti v bezpečí a dobře se baví.', | ||
}, | ||
{ | ||
id: 'vaclavak', | ||
name: 'Koutek Václavák', | ||
address: 'Václavské nám. 816/49, 110 00 Praha 1', | ||
capacity: 30, | ||
open: { | ||
mon: '7:30 - 18:00', | ||
tue: '7:30 - 18:00', | ||
wed: '7:30 - 18:00', | ||
thu: '7:30 - 18:00', | ||
fri: '7:30 - 18:00', | ||
sat: null, | ||
sun: null, | ||
}, | ||
info: 'Tento koutek je jedním z největších v Praze a nabízí širokou škálu aktivit pro děti, jako jsou kreativní workshopy, hudební lekce a taneční kurzy. Koutek má také velkou zahradu, kde se děti mohou hrát na čerstvém vzduchu a užít si slunečné dny. Pro rodiče je k dispozici relaxační zóna, kde se mohou odpočinout a relaxovat.', | ||
}, | ||
]; | ||
|
||
export const getAllCenters = () => { | ||
return centers; | ||
}; | ||
|
||
export const getCenterById = (id) => { | ||
return centers.find((center) => center.id === id); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
--- | ||
title: Pobočky dětského koutku | ||
demand: 4 | ||
--- | ||
|
||
Budeme pokračovat v projektu dětského koutku. Přidáme možnost zobrazit seznam poboček a každou pobočku rozkliknout pro získání více informaci. | ||
|
||
1. Pokračujte v projektu z předchozího cvičení. | ||
1. Nejprve do projektu přidejte stránku, která správně ošetří přístup na neexistující stránku, tedy chybu 404. | ||
1. Dále přidejte do navigace stránku _Pobočky_ a vytvořte pro ni samostatnou komponentu `CentersPage`. Na této stránce budeme chtít zobrazit jednotlivé pobočky našeho dětského koutku (viz další bod). | ||
1. Do složky `src` si stáhněte soubor [`centers.js`](assets/centers.js), který bude představovat databázi poboček. | ||
1. Do souboru s komponentou pro seznam poboček si importuje funkci `getAllCenters`. Pomocí mapování zobrazte seznam odkazů na jednotlivé pobočky. Odkaz bude vždy cesta `/pobocky/id-pobocky`. Zatím nezobrazujte detail pobočky, pouze její název a adresu. Tento seznam bude sloužit jako navigace mezi jednotlivými pobočkami. | ||
1. Vytvořte komponentu `CenterDetail` pro zobrazení detailu pobočky. Tato komponenta bude sídlit pod cestou `/pobocky/:id`. Pomocí `useParams` a funkce `getCenterById` získejte položku podle parametru `:id`. Zobrazte detail pobočky s otvíracími hodinami i popisem. | ||
1. Komponentu `CenterDetail` zobrazte jako `<Outlet />` uvnitř komponenty `CentersPage`. | ||
1. Nyní by měla stránka správně fungovat. Po kliknutí na pobočku se uživatel dostane na stránku s detailem každé pobočky. Zároveň na stránce uvidí hlavní navigaci i seznam ostatních poboček. | ||
|
||
#### Bonus | ||
|
||
1. Přidejte zajímavé featury z dokumentace. Například stylování odkazů podle toho, která stránka je zrovna aktivní. S tím nám pomůže komponenta [NavLink](https://reactrouter.com/en/6.10.0/start/tutorial#active-link-styling). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
title: React Router | ||
lead: 'Pomocí routeru dokážeme v Reactu vyrobit vícestránkovou aplikaci.' | ||
access: 'claim' | ||
sections: | ||
- spa | ||
- router | ||
- cv-router | ||
- chyby | ||
- dynamicky-obsah | ||
- cv-dynamicke-stranky | ||
- cv-projekt |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
## Fáze vývoje webové aplikace | ||
|
||
V mnoha cvičeních a projektech v tomto kurzu už jste jistě zažili, že i tu úplně nejobyčejnější webovou aplikaci nikdo nezvládne napsat najednou, takříkajíc z voleje. Vždy je potřeba si práci nějak dopředu rozvrhnout a naplánovat si jednotlivé fáze. | ||
|
||
Při vývoji webových aplikaci většinou postupujeme podle následujícího schématu: | ||
|
||
1. **Návrh** – připravíme návrh aplikace, který může být v podobě wireframů, grafického návrhu, nebo jenom výčtu požadavků. V této fázi se také rozhodneme, jaké technologie budeme používat a jakým způsobem budeme aplikaci vyvíjet. Návrh vzniká na základě anlýzy požadavků zadavatele, což může být náš klient, nebo třeba jenom my sami. | ||
1. **Grafický design** – připravíme grafický návrh. V této fázi se rozhodneme o barvách, typografii, velikosti elementů, UX atd. Výsledkem je grafický návrh, který může být vytvořen v nějakém grafickém editoru, nebo třeba jenom v HTML a CSS. | ||
1. **Návrh architektury** – rozhodneme se, jakou bude naše aplikace mít strukturu, jaké komponenty budeme potřebovat, jaká data budeme ukládat a jakým způsobem je budeme zpracovávat. Výsledkem je návrh architektury aplikace, který může být vytvořen v nějakém nástroji k tomu určeném, nebo může být pro menší projekty jen v naší hlavě. | ||
1. **Implementace** – naprogramujeme aplikaci podle návrhu. Výsledkem je funkční aplikace, která ještě nemusí být plně odladěná. | ||
1. **Testování** – otestujeme aplikaci a odstraníme všechny chyby. Výsledkem je funkční aplikace, která je plně odladěná. | ||
|
||
V praxi se tyto fáze často prolínají a některé z nich se mohou opakovat. Například při tvorbě architektury můžeme zjistit, že náš původní návrh není úplně ideální a musíme se vrátit zpět. Nebo při implementaci můžeme zjistit, že náš původní návrh architektury nebyl úplně ideální a je potřeba ji upravit nebo úplně předělat. | ||
|
||
## Architektura aplikace | ||
|
||
V našem případě si při návrhu architektury budeme soustředit na následující body: | ||
|
||
1. **Struktura dat** – jaká data budeme potřebovat ukládat a spravovat pomocí našeho API. Výsledkem tohoto bodu mohou být například ukázkové JSON soubory s daty pro `jsonhost`. | ||
1. **Struktura komponent** – jaké komponenty budeme potřebovat, jak budou získávat data a jak budou spolu komunikovat. Výsledkem tohoto bodu jednoduchý popis jednotlivých komponent ve formátu, který si za chvíli ukážeme. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
## React Router | ||
|
||
Napsat navigaci mezi stránkami v čistém JavaScriptu jste si už vyzkoušeli v předchozím kurzu. Co se Reactu týká, máme situaci malinko jednodušší. Existuje totiž standardní knihovna pro routing, kterou používá většina reactových projektů na celém světě. Jmenuje [React Router](https://reactrouter.com/) a nainstalovat si ji můžete jako závislost přes _npm_ a následně z ní můžeme používat připravené komponenty přímo v našem kódu. | ||
|
||
### Instalace a používání knihovny | ||
|
||
Do existujícího projektu můžeme nainstalovat React Router knihovnu přest terminál pomocí _npm_. | ||
|
||
```sh | ||
npm install react-router-dom | ||
``` | ||
|
||
Nyní máme v projektu k dispozici celou škálu komponent, se kterými můzeme pracovat. Stačí si je správně naimportovat a použít jako kteroukoliv jinou komponentu. | ||
|
||
Vytvořme pro začátek kostru webové aplikace pro vedení účetnictví. | ||
|
||
```js | ||
import React from 'react'; | ||
import { createRoot } from 'react-dom/client'; | ||
import { createBrowserRouter, RouterProvider, Link } from 'react-router-dom'; | ||
import './style.css'; | ||
|
||
const App = () => { | ||
return ( | ||
<div className="container"> | ||
<h1>Bookkeeper!</h1> | ||
<nav> | ||
<Link to="/invoices">Invoices</Link> | ||
<span> | </span> | ||
<Link to="/expenses">Expenses</Link> | ||
</nav> | ||
</div> | ||
); | ||
}; | ||
|
||
const ExpensesPage = () => { | ||
return ( | ||
<main> | ||
<h2>Expenses</h2> | ||
<p>Here are your business expenses for the last month</p> | ||
</main> | ||
); | ||
}; | ||
|
||
const InvoicesPage = () => { | ||
return ( | ||
<main> | ||
<h2>Invoices</h2> | ||
<p>Here are your issued invoices for the last month</p> | ||
</main> | ||
); | ||
}; | ||
|
||
const router = createBrowserRouter([ | ||
{ | ||
path: '/', | ||
element: <App />, | ||
}, | ||
{ | ||
path: '/expenses', | ||
element: <ExpensesPage />, | ||
}, | ||
{ | ||
path: '/invoices', | ||
element: <InvoicesPage />, | ||
}, | ||
]); | ||
|
||
createRoot(document.querySelector('#app')).render( | ||
<RouterProvider router={router} /> | ||
); | ||
``` | ||
|
||
Na začátku aplikace jsme vytvořili komponentu `App`, která se zobrazí jako hlavní stránka. Jednotlivé odkazy pak vedou na dvě podstránky `ExpensesPage` a `InvoicesPage`. | ||
|
||
### Komponenta `Link` | ||
|
||
Všimněte si, že pro navigaci mezi stránkami používáme místo obyčejného prvku `<a href>` komponentu `Link`. To je velmi důležité, protože kdybychom použili normální HTML odkazy, vždy bychom tím poslali požadavek na novou stránku na server. V SPA aplikacích však server posílá vždy jednu a tutéž stránku `index.html` jako odpověd na všechny cesty v URL. Soubor `index.html` už však dávno máme načtený, takže jej nepotřebujeme znovu. Dotaz na server je zbytečný a zbytečně by způsobil refresh stránky. My naopak chceme, aby se ze serveru nic nenačítalo a přepnutí stránky se stalo pouze na frontendu v režii React Routeru. | ||
|
||
### Routování části stránky | ||
|
||
Naše aplikace má nevýhodu v tom, že nám při přepnutí na jednotlivé stránky zmizí navigace. Weby často fungují tak, že při přepínání mezi stránkami se zachovává například hlavička a patička. Tohoto chování docílíme pomocí tazvaných _child routes_ a komponenty `Outlet`. | ||
|
||
Náš objekt s routami upravíme takto: | ||
|
||
```js | ||
const router = createBrowserRouter([ | ||
{ | ||
path: '/', | ||
element: <App />, | ||
children: [ | ||
{ | ||
path: 'expenses', | ||
element: <ExpensesPage />, | ||
}, | ||
{ | ||
path: 'invoices', | ||
element: <InvoicesPage />, | ||
}, | ||
], | ||
}, | ||
]); | ||
``` | ||
|
||
Vytvořili jsme tak dva potomky naší kořenové routy. Nyní musíme routeru říct, kde na stránce má naše potomky zobrazovat. To zařídíme pomoctí komponenty `Outlet`. | ||
|
||
```jsx | ||
const App = () => { | ||
return ( | ||
<div className="container"> | ||
<h1>Bookkeeper!</h1> | ||
<nav> | ||
<Link to="/invoices">Invoices</Link> | ||
<span> | </span> | ||
<Link to="/expenses">Expenses</Link> | ||
</nav> | ||
<Outlet /> | ||
</div> | ||
); | ||
}; | ||
``` | ||
|
||
Nyní už naše aplikace bude mnohem hezčí a přehlednější. |
Oops, something went wrong.