Kurs Next.js · Moduł 1: Konfiguracja Next.js
Wprowadzenie do React i Next.js - historia, zalety, ekosystem
W tej lekcji7
Witaj w Metropolii Quantum, centrum technologicznym roku 2150, gdzie budynki sięgają nieba, pojazdy unoszą się w powietrzu, a wszechobecna sieć kwantowa łączy wszystkie aspekty codziennego życia. Technologia jest tu integralną częścią społeczeństwa, podobnie jak React i Next.js są fundamentalnymi składnikami nowoczesnego ekosystemu webowego.
Narodziny technologii React
W historii rozwoju technologii webowych React był jak pierwszy sprawny silnik antygrawitacyjny - zrewolucjonizował sposób, w jaki konstruujemy interfejsy użytkownika. Stworzony w 2011 roku przez inżyniera Facebooka (obecnie Meta) i udostępniony jako open source w 2013 roku, React wprowadził przełomową koncepcję: deklaratywne komponenty z wirtualnym DOM.
React rozwiązał jeden z najważniejszych problemów rozwoju aplikacji webowych - złożoność aktualizacji interfejsu użytkownika. Zamiast bezpośrednio manipulować DOM (co było kosztowne i podatne na błędy), React pozwolił deweloperom myśleć w kategoriach stanu i komponentów:
1// Prosty komponent React
2function WelcomePanel() {
3 const [userName, setUserName] = React.useState("Obywatelu");
4
5 return (
6 <div className="quantum-panel">
7 <h2>Witaj, {userName}!</h2>
8 <p>Terminal Metropolii Quantum do Twoich usług.</p>
9 <button onClick={() => setUserName("Administratorze")}>
10 Zaloguj się
11 </button>
12 </div>
13 );
14}Komponent powyżej to jak inteligentny panel sterowania w Metropolii Quantum - automatycznie reaguje na zmiany stanu (w tym przypadku userName), bez konieczności ręcznego sterowania każdym elementem interfejsu.
Starszy kod Reacta używa też komponentów klasowych (class Panel extends React.Component). Nadal działają, ale nowe komponenty pisze się jako funkcje.
Ewolucja do Next.js
Pomimo swoich zalet React był tylko biblioteką interfejsu użytkownika. Deweloperzy wciąż musieli samodzielnie konfigurować routing, optymalizację wydajności, renderowanie po stronie serwera i wiele innych aspektów.
Next.js pojawił się w 2016 roku jako framework zbudowany na bazie Reacta, dostarczający gotowe rozwiązania dla tych problemów. Można to porównać do przejścia od prototypu silnika antygrawitacyjnego do w pełni funkcjonalnego pojazdu latającego w Metropolii Quantum.
Najważniejsze cechy Next.js:
Renderowanie hybrydowe - możliwość renderowania zarówno po stronie serwera (SSR), statycznie (SSG), jak i po stronie klienta
Routing oparty na systemie plików - tworzenie ścieżek aplikacji poprzez strukturę folderów
Automatyczny code splitting - dzielenie kodu na mniejsze części, ładowane tylko wtedy, gdy są potrzebne
Optymalizacja obrazów - automatyczne przetwarzanie i serwowanie obrazów w optymalnych formatach
Zero-config - działa natychmiast po instalacji, z minimalną konfiguracją
API Routes - tworzenie endpointów API w tym samym projekcie co frontend
Next.js 16 i App Router
W Next.js 16 zalecanym routerem jest App Router - rewolucyjna zmiana, która pojawiła się w Next.js 13 i oznacza całkowicie nowe podejście do organizacji aplikacji (starszy Pages Router nadal działa). Jest to jak przejście od tradycyjnych pojazdów latających do teleportacji kwantowej w Metropolii Quantum - fundamentalna zmiana paradygmatu.
App Router wykorzystuje najnowsze funkcje React 19.2, w tym React Server Components, które zmieniają tradycyjny model aplikacji webowych. Zamiast traktować całą aplikację jako jednostkę renderowaną po stronie klienta, App Router pozwala na elastyczne mieszanie komponentów renderowanych na serwerze i kliencie.
1// app/dashboard/page.tsx - Server Component
2export default async function DashboardPage() {
3 // Ten kod wykonuje się TYLKO na serwerze
4 const dashboardData = await fetchDashboardData();
5
6 return (
7 <main className="quantum-dashboard">
8 <h1>Panel Kontrolny Metropolii Quantum</h1>
9 <StatusPanel data={dashboardData.status} />
10 <InteractiveControls /> {/* To będzie komponent kliencki */}
11 </main>
12 );
13}1// app/dashboard/interactive-controls.tsx - Client Component
2"use client"; // Ta dyrektywa oznacza komponent kliencki
3
4import { useState } from 'react';
5
6export default function InteractiveControls() {
7 // Ten kod wykonuje się w przeglądarce użytkownika
8 const [activeSystem, setActiveSystem] = useState('energy');
9
10 return (
11 <div className="control-panel">
12 <h2>System: {activeSystem}</h2>
13 <button onClick={() => setActiveSystem('transport')}>
14 Transport
15 </button>
16 <button onClick={() => setActiveSystem('energy')}>
17 Energia
18 </button>
19 <button onClick={() => setActiveSystem('security')}>
20 Bezpieczeństwo
21 </button>
22 </div>
23 );
24}Ekosystem React i Next.js
Ekosystem React i Next.js to jak zaawansowana infrastruktura Metropolii Quantum - rozbudowana, zintegrowana i ciągle ewoluująca. Oto kluczowe elementy tego ekosystemu:
Biblioteki zarządzania stanem:
- Redux - kompleksowe rozwiązanie dla złożonych aplikacji
- Zustand - lżejsza, prostsza alternatywa
- Jotai - atomowa architektura stanu
- React Query / SWR - zarządzanie stanem serwerowym
Biblioteki stylizacji:
- Tailwind CSS - system klas użytkowych
- Styled Components / Emotion - CSS-in-JS
- CSS Modules - wbudowane w Next.js
- Chakra UI / MUI - gotowe komponenty UI
Testowanie:
- Jest - framework testowy
- React Testing Library - testowanie komponentów
- Cypress / Playwright - testy end-to-end
Narzędzia deweloperskie:
- ESLint - statyczna analiza kodu
- Prettier - formatowanie kodu
- TypeScript - typowanie statyczne
- Next.js DevTools - narzędzia deweloperskie Next.js
Zalety używania React i Next.js
Używanie React i Next.js w projektach webowych przynosi korzyści podobne do tych, jakie mieszkańcy Metropolii Quantum czerpią z zaawansowanej infrastruktury miasta:
Wydajność - optymalizacje takie jak code splitting, wstępne ładowanie, optymalizacja obrazów
Skalowalność - architektura oparta na komponentach ułatwia zarządzanie dużymi aplikacjami
Doświadczenie dewelopera - szybka pętla zwrotna dzięki hot reloadingowi, jasna struktura projektu
SEO - renderowanie po stronie serwera i generowanie statyczne poprawiają indeksowanie przez wyszukiwarki
Ekosystem - bogaty wybór bibliotek i narzędzi
Społeczność - ogromna, aktywna społeczność i dokumentacja
Struktura projektu Next.js z App Routerem
W App Routerze struktura projektu przypomina mapy dzielnic i systemy transportowe Metropolii Quantum - wszystko ma swoje miejsce i przeznaczenie:
1app/ # Główny katalog aplikacji
2├── layout.tsx # Główny układ aplikacji
3├── page.tsx # Strona główna
4├── globals.css # Style globalne
5├── dashboard/ # Trasa /dashboard
6│ ├── layout.tsx # Układ dla całej sekcji dashboard
7│ ├── page.tsx # Strona /dashboard
8│ └── analytics/ # Trasa /dashboard/analytics
9│ └── page.tsx # Strona /dashboard/analytics
10├── auth/ # Trasa /auth
11│ ├── login/ # Trasa /auth/login
12│ │ └── page.tsx # Strona /auth/login
13│ └── register/ # Trasa /auth/register
14│ └── page.tsx # Strona /auth/register
15└── api/ # Trasy API
16 └── status/ # Endpoint /api/status
17 └── route.ts # Obsługa API dla /api/statusW tej strukturze nawigacja jest intuicyjna, a komponenty współdzielone są automatycznie między stronami. Jest to ogromna zaleta w porównaniu z tradycyjnymi aplikacjami React, gdzie zarządzanie routingiem mogło być skomplikowane.
Podsumowanie
React i Next.js stanowią potężny duet w nowoczesnym rozwoju aplikacji webowych, podobnie jak sieć kwantowa i zaawansowana infrastruktura stanowią rdzeń funkcjonowania Metropolii Quantum.
React dostarcza model komponentów i zarządzania stanem, który czyni tworzenie interfejsów użytkownika bardziej przewidywalnym i łatwiejszym w utrzymaniu. Next.js dodaje strukturę, optymalizacje i narzędzia, które przekształcają React w kompletną platformę do budowania aplikacji webowych.
W miarę jak będziemy zagłębiać się w kolejne moduły, poznasz praktyczne zastosowania tych technologii, podobnie jak odkrywając Metropolię Quantum, poznasz wszystkie jej zaawansowane systemy.
Kod do tej lekcji: App.tsx
1// React i Next.js - Metropolis Quantum
2import React, { useState, useEffect } from 'react';
3import './App.css';
4
5console.log("Witaj w Metropolis Quantum!");
6console.log("Poznajemy React i Next.js - przyszłość web developmentu\n");
7
8// ===========================================
9// 1. Komponenty Reacta - fundamenty
10// ===========================================
11console.log("=== 1. KOMPONENTY REACTA ===");
12
13// Funkcyjny komponent React
14const QuantumButton: React.FC<{
15 children: React.ReactNode;
16 onClick: () => void;
17 variant?: 'primary' | 'secondary' | 'quantum';
18}> = ({ children, onClick, variant = 'primary' }) => {
19 const [isActivated, setIsActivated] = useState(false);
20
21 const handleClick = () => {
22 setIsActivated(true);
23 onClick();
24 setTimeout(() => setIsActivated(false), 300);
25 };
26
27 return (
28 <button
29 className={`quantum-btn quantum-btn--${variant} ${isActivated ? 'activated' : ''}`}
30 onClick={handleClick}
31 >
32 {children}
33 {isActivated && <span className="quantum-ripple"></span>}
34 </button>
35 );
36};
37
38// Komponent z hookiem useState
39const QuantumCounter: React.FC = () => {
40 const [energy, setEnergy] = useState(0);
41 const [isCharging, setIsCharging] = useState(false);
42
43 const generateEnergy = () => {
44 setIsCharging(true);
45
46 const interval = setInterval(() => {
47 setEnergy(prev => {
48 const newEnergy = prev + Math.floor(Math.random() * 10) + 1;
49 if (newEnergy >= 100) {
50 clearInterval(interval);
51 setIsCharging(false);
52 console.log("Bateria kwantowa w pełni naładowana!");
53 return 100;
54 }
55 return newEnergy;
56 });
57 }, 200);
58 };
59
60 const resetEnergy = () => {
61 setEnergy(0);
62 setIsCharging(false);
63 console.log("Bateria kwantowa zresetowana");
64 };
65
66 return (
67 <div className="quantum-counter">
68 <h3>Kwantowy generator energii</h3>
69 <div className="energy-display">
70 <div className="energy-bar">
71 <div
72 className="energy-fill"
73 style={{ width: `${energy}%` }}
74 ></div>
75 </div>
76 <span className="energy-text">{energy}% energii</span>
77 </div>
78
79 <div className="counter-controls">
80 <QuantumButton
81 onClick={generateEnergy}
82 variant="quantum"
83 disabled={isCharging}
84 >
85 {isCharging ? 'Ładowanie...' : 'Generuj energię'}
86 </QuantumButton>
87
88 <QuantumButton
89 onClick={resetEnergy}
90 variant="secondary"
91 >
92 Resetuj
93 </QuantumButton>
94 </div>
95
96 {energy === 100 && (
97 <div className="achievement">
98 Osiągnięcie odblokowane: Kwantowy Mistrz!
99 </div>
100 )}
101 </div>
102 );
103};
104
105// ===========================================
106// 2. Hook useEffect - efekty uboczne
107// ===========================================
108console.log("=== 2. HOOK USEEFFECT ===");
109
110const QuantumClock: React.FC = () => {
111 const [currentTime, setCurrentTime] = useState(new Date());
112 const [quantumTime, setQuantumTime] = useState(0);
113
114 // useEffect dla aktualizacji czasu
115 useEffect(() => {
116 console.log("Zegar kwantowy włączony");
117
118 const timer = setInterval(() => {
119 setCurrentTime(new Date());
120 setQuantumTime(prev => prev + 1);
121 }, 1000);
122
123 // Funkcja sprzątająca
124 return () => {
125 clearInterval(timer);
126 console.log("Zegar kwantowy wyłączony");
127 };
128 }, []); // Pusta tablica zależności - uruchamia się raz
129
130 // useEffect z zależnością
131 useEffect(() => {
132 if (quantumTime > 0 && quantumTime % 10 === 0) {
133 console.log(`Kwantowy punkt kontrolny: ${quantumTime} sekund`);
134 }
135 }, [quantumTime]); // Uruchamia się, gdy zmieni się quantumTime
136
137 const formatTime = (date: Date) => {
138 return date.toLocaleTimeString('pl-PL');
139 };
140
141 return (
142 <div className="quantum-clock">
143 <h3>Kwantowy portal czasu</h3>
144 <div className="time-display">
145 <div className="real-time">
146 <span className="time-label">Czas ziemski:</span>
147 <span className="time-value">{formatTime(currentTime)}</span>
148 </div>
149 <div className="quantum-time">
150 <span className="time-label">Czas kwantowy:</span>
151 <span className="time-value">{quantumTime}s</span>
152 </div>
153 </div>
154 </div>
155 );
156};
157
158// ===========================================
159// 3. React a tradycyjny DOM
160// ===========================================
161console.log("=== 3. REACT A TRADYCYJNY DOM ===");
162
163const DOMComparison: React.FC = () => {
164 const [items, setItems] = useState<string[]>(['Quantum Core', 'Energy Shield', 'Plasma Drive']);
165 const [newItem, setNewItem] = useState('');
166
167 // Sposób Reacta - deklaratywny
168 const addItemReact = () => {
169 if (newItem.trim()) {
170 setItems(prev => [...prev, newItem.trim()]);
171 setNewItem('');
172 console.log(`Sposób Reacta: dodano "${newItem}" do kwantowego ekwipunku`);
173 }
174 };
175
176 // Tradycyjny sposób z DOM (dla porównania)
177 const addItemTraditional = () => {
178 console.log("Tradycyjny sposób z DOM (niezalecany w React):");
179 console.log(" 1. document.getElementById('list')");
180 console.log(" 2. createElement('li')");
181 console.log(" 3. appendChild(listItem)");
182 console.log(" 4. Ręczne zarządzanie obsługą zdarzeń");
183 console.log(" 5. Ręczna synchronizacja stanu");
184 };
185
186 return (
187 <div className="dom-comparison">
188 <h3>React a tradycyjny DOM</h3>
189
190 <div className="react-way">
191 <h4>Sposób Reacta (deklaratywny)</h4>
192 <div className="input-group">
193 <input
194 type="text"
195 value={newItem}
196 onChange={(e) => setNewItem(e.target.value)}
197 placeholder="Wpisz komponent kwantowy..."
198 className="quantum-input"
199 />
200 <QuantumButton onClick={addItemReact}>
201 Dodaj do ekwipunku
202 </QuantumButton>
203 </div>
204
205 <div className="inventory-list">
206 <h5>Kwantowy ekwipunek:</h5>
207 <ul>
208 {items.map((item, index) => (
209 <li key={index} className="inventory-item">
210 {item}
211 <button
212 onClick={() => setItems(prev => prev.filter((_, i) => i !== index))}
213 className="remove-btn"
214 >
215 ×
216 </button>
217 </li>
218 ))}
219 </ul>
220 </div>
221 </div>
222
223 <div className="traditional-way">
224 <h4>Tradycyjny sposób z DOM</h4>
225 <QuantumButton onClick={addItemTraditional} variant="secondary">
226 Pokaż tradycyjne podejście
227 </QuantumButton>
228 <p className="comparison-note">
229 React sam aktualizuje DOM dzięki Virtual DOM!
230 </p>
231 </div>
232 </div>
233 );
234};
235
236// ===========================================
237// 4. Kompozycja komponentów
238// ===========================================
239console.log("=== 4. KOMPOZYCJA KOMPONENTÓW ===");
240
241interface QuantumModuleProps {
242 title: string;
243 status: 'online' | 'offline' | 'maintenance';
244 children: React.ReactNode;
245}
246
247const QuantumModule: React.FC<QuantumModuleProps> = ({ title, status, children }) => {
248 const getStatusColor = () => {
249 switch (status) {
250 case 'online': return '#4caf50';
251 case 'offline': return '#f44336';
252 case 'maintenance': return '#ff9800';
253 default: return '#999';
254 }
255 };
256
257 return (
258 <div className="quantum-module">
259 <div className="module-header">
260 <h4>{title}</h4>
261 <div
262 className={`status-indicator status-${status}`}
263 style={{ backgroundColor: getStatusColor() }}
264 >
265 {status.toUpperCase()}
266 </div>
267 </div>
268 <div className="module-content">
269 {children}
270 </div>
271 </div>
272 );
273};
274
275const MetropolisControlPanel: React.FC = () => {
276 const [systemStatus, setSystemStatus] = useState<'online' | 'offline' | 'maintenance'>('online');
277
278 const toggleSystem = () => {
279 setSystemStatus(prev => {
280 const statuses: Array<'online' | 'offline' | 'maintenance'> = ['online', 'maintenance', 'offline'];
281 const currentIndex = statuses.indexOf(prev);
282 const nextStatus = statuses[(currentIndex + 1) % statuses.length];
283 console.log(`Zmiana statusu systemu: ${prev} → ${nextStatus}`);
284 return nextStatus;
285 });
286 };
287
288 return (
289 <div className="control-panel">
290 <h3>Panel sterowania Metropolii</h3>
291
292 <QuantumModule title="System napędu" status={systemStatus}>
293 <p>Kwantowe silniki napędowe pracują z optymalną wydajnością</p>
294 <div className="metric">
295 <span>Prędkość: </span>
296 <span className="value">
297 {systemStatus === 'online' ? '299,792,458 m/s' : 'OFFLINE'}
298 </span>
299 </div>
300 </QuantumModule>
301
302 <QuantumModule title="Sieć obronna" status={systemStatus}>
303 <p>Tarcze energetyczne chroniące metropolię</p>
304 <div className="metric">
305 <span>Moc tarczy: </span>
306 <span className="value">
307 {systemStatus === 'online' ? '98.7%' : 'OFFLINE'}
308 </span>
309 </div>
310 </QuantumModule>
311
312 <QuantumModule title="Centrum komunikacji" status={systemStatus}>
313 <p>Sieć komunikacji oparta na splątaniu kwantowym</p>
314 <div className="metric">
315 <span>Siła sygnału: </span>
316 <span className="value">
317 {systemStatus === 'online' ? 'Doskonała' : 'OFFLINE'}
318 </span>
319 </div>
320 </QuantumModule>
321
322 <div className="panel-controls">
323 <QuantumButton onClick={toggleSystem} variant="quantum">
324 Zmień status systemu
325 </QuantumButton>
326 </div>
327 </div>
328 );
329};
330
331// ===========================================
332// 5. Podgląd Next.js
333// ===========================================
334console.log("=== 5. PODGLĄD NEXT.JS ===");
335
336const NextJSPreview: React.FC = () => {
337 const [currentFeature, setCurrentFeature] = useState(0);
338
339 const nextjsFeatures = [
340 {
341 title: "App Router",
342 description: "Routing oparty na plikach, z layoutami i zagnieżdżonymi ścieżkami",
343 code: `app/
344├── layout.tsx // Główny layout
345├── page.tsx // Strona główna
346├── dashboard/
347│ ├── layout.tsx // Layout panelu
348│ └── page.tsx // Strona panelu
349└── api/
350 └── route.ts // Endpoint API`
351 },
352 {
353 title: "Server Components",
354 description: "Renderowanie komponentów na serwerze dla lepszej wydajności",
355 code: `// app/quantum/page.tsx
356async function QuantumPage() {
357 // To działa na serwerze!
358 const data = await fetch('https://api.quantum.com/data');
359 const quantumData = await data.json();
360
361 return <div>{quantumData.energy}</div>;
362}`
363 },
364 {
365 title: "Strategie renderowania",
366 description: "SSR, SSG, ISR - wybierz najlepszą strategię dla swojej aplikacji",
367 code: `// Generowanie statyczne (SSG)
368export async function generateStaticParams() {
369 return [{ id: '1' }, { id: '2' }];
370}
371
372// Renderowanie po stronie serwera (SSR)
373async function DynamicPage() {
374 const data = await fetch(url, { cache: 'no-store' });
375 return <div>{data}</div>;
376}`
377 },
378 {
379 title: "Wbudowane optymalizacje",
380 description: "Automatyczny podział kodu (code splitting), optymalizacja obrazów i fontów",
381 code: `import Image from 'next/image';
382import { Inter } from 'next/font/google';
383
384const inter = Inter({ subsets: ['latin'] });
385
386export default function Page() {
387 return (
388 <div className={inter.className}>
389 <Image
390 src="/quantum.jpg"
391 alt="Quantum City"
392 width={800}
393 height={600}
394 priority
395 />
396 </div>
397 );
398}`
399 }
400 ];
401
402 const nextFeature = () => {
403 setCurrentFeature(prev => (prev + 1) % nextjsFeatures.length);
404 };
405
406 const prevFeature = () => {
407 setCurrentFeature(prev => (prev - 1 + nextjsFeatures.length) % nextjsFeatures.length);
408 };
409
410 const feature = nextjsFeatures[currentFeature];
411
412 return (
413 <div className="nextjs-preview">
414 <h3>Funkcje Next.js 16</h3>
415
416 <div className="feature-showcase">
417 <div className="feature-header">
418 <h4>{feature.title}</h4>
419 <p>{feature.description}</p>
420 </div>
421
422 <div className="feature-code">
423 <pre><code>{feature.code}</code></pre>
424 </div>
425
426 <div className="feature-navigation">
427 <QuantumButton onClick={prevFeature} variant="secondary">
428 Poprzednia
429 </QuantumButton>
430
431 <span className="feature-counter">
432 {currentFeature + 1} / {nextjsFeatures.length}
433 </span>
434
435 <QuantumButton onClick={nextFeature} variant="secondary">
436 Następna
437 </QuantumButton>
438 </div>
439 </div>
440 </div>
441 );
442};
443
444// ===========================================
445// 6. Główny komponent App
446// ===========================================
447const App: React.FC = () => {
448 const [activeSection, setActiveSection] = useState('intro');
449
450 useEffect(() => {
451 console.log("Aplikacja Metropolis Quantum zainicjalizowana");
452 console.log("Czas poznać React i Next.js!");
453 }, []);
454
455 const sections = {
456 intro: { title: "Wprowadzenie", component: () => (
457 <div className="intro-section">
458 <h2>Witaj w Metropolis Quantum!</h2>
459 <p>
460 W futurystycznym mieście Metropolis Quantum, gdzie technologia spotyka się z magią,
461 poznajemy fundamenty React i Next.js - narzędzi, które pozwalają budować
462 interaktywne aplikacje webowe nowej generacji.
463 </p>
464 <div className="intro-features">
465 <div className="feature-card">
466 <h4>React</h4>
467 <p>Biblioteka do budowania interfejsów użytkownika</p>
468 </div>
469 <div className="feature-card">
470 <h4>Next.js</h4>
471 <p>Framework React z dodatkowymi możliwościami</p>
472 </div>
473 <div className="feature-card">
474 <h4>TypeScript</h4>
475 <p>Statyczne typowanie dla większego bezpieczeństwa</p>
476 </div>
477 </div>
478 </div>
479 )},
480 components: { title: "Komponenty", component: () => <QuantumCounter /> },
481 hooks: { title: "Hooki", component: () => <QuantumClock /> },
482 comparison: { title: "Porównanie DOM", component: () => <DOMComparison /> },
483 composition: { title: "Kompozycja", component: () => <MetropolisControlPanel /> },
484 nextjs: { title: "Next.js", component: () => <NextJSPreview /> }
485 };
486
487 return (
488 <div className="metropolis-app">
489 <header className="app-header">
490 <h1>Metropolis Quantum</h1>
491 <p>Platforma do nauki React i Next.js</p>
492 </header>
493
494 <nav className="app-navigation">
495 {Object.entries(sections).map(([key, section]) => (
496 <QuantumButton
497 key={key}
498 onClick={() => setActiveSection(key)}
499 variant={activeSection === key ? 'quantum' : 'secondary'}
500 >
501 {section.title}
502 </QuantumButton>
503 ))}
504 </nav>
505
506 <main className="app-content">
507 <div className="content-container">
508 {sections[activeSection as keyof typeof sections].component()}
509 </div>
510 </main>
511
512 <footer className="app-footer">
513 <p>Napędzane technologią kwantową • Ucz się React i Next.js</p>
514 </footer>
515 </div>
516 );
517};
518
519export default App;Widzisz błąd w tej lekcji?
Sprawdź się
Odpowiedz na pytania z tej lekcji. Wybierz odpowiedź, a od razu zobaczysz, czy jest poprawna.
1. W którym roku React został udostępniony publicznie jako open source?
2. React został stworzony przez:
3. Główną zaletą React jest:
Zadania praktyczne w grze
- Edytor kodu
Utwórz komponent funkcyjny HelloWorld, który zwraca nagłówek <h1> z komunikatem powitalnym, np. „Witaj w Metropolis Quantum!”.
- Klikanie w kolejności
Ułóż deklarację komponentu funkcyjnego w React