Komponenty złożone z Context
Udostępni Pan/Pani niejawny stan między komponentem nadrzędnym a wyznaczonymi komponentami potomnymi za pomocą Context, modelując interfejsy API takie jak i .
Komponenty złożone z Context to bezpłatna lekcja Frontend Academy na CoddyKit. To lekcja 1 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Frontend Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Frontend Academy zawiera 4 lekcji w sumie.
Czym są komponenty złożone?
Komponenty złożone to zestaw powiązanych komponentów zaprojektowanych do wspólnego działania jako jedna całość — podobnie jak <select> i <option> w HTML. Rodzic niejawnie udostępnia stan przypisanym do niego komponentom potomnym.
Cel: przejrzystsze API
Zamiast <Select options={[...]} value={x} onChange={...} /> można napisać <Select><Option value="a">Apple</Option></Select>. Taka struktura jest deklaratywna i naturalna dla JSX.
Podejście naiwne (problem)
Przekazywanie stanu przez właściwości wymaga od użytkownika skonfigurowania wszystkiego. Komponenty potomne nie wiedzą automatycznie o stanie rodzica.
// Without compound pattern — verbose:
<Tabs activeIndex={0} onChange={setIndex}>
<TabList>
<Tab index={0}>Home</Tab>
<Tab index={1}>Profile</Tab>
</TabList>
</Tabs>Context jako łącznik
Rodzic tworzy Context ze współdzielonym stanem i udostępnia go. Komponenty potomne korzystają z kontekstu — bez jawnego przekazywania właściwości.
import { createContext, useContext, useState } from 'react';
const TabsContext = createContext(null);
export function Tabs({ children, defaultIndex = 0 }) {
const [activeIndex, setActiveIndex] = useState(defaultIndex);
return (
<TabsContext.Provider value={{ activeIndex, setActiveIndex }}>
<div className="tabs">{children}</div>
</TabsContext.Provider>
);
}Komponenty potomne korzystają z kontekstu
Każdy komponent potomny odczytuje dane z kontekstu — właściwości nie trzeba przekazywać przez kolejne poziomy drzewa.
export function Tab({ index, children }) {
const { activeIndex, setActiveIndex } = useContext(TabsContext);
const isActive = activeIndex === index;
return (
<button
className={isActive ? 'active' : ''}
onClick={() => setActiveIndex(index)}
>
{children}
</button>
);
}
export function Panel({ index, children }) {
const { activeIndex } = useContext(TabsContext);
if (activeIndex !== index) return null;
return <div className="panel">{children}</div>;
}Właściwości statyczne ułatwiające odnalezienie
Należy dołączyć podkomponenty do rodzica, aby użytkownicy mogli znaleźć je dzięki autouzupełnianiu.
Tabs.Tab = Tab;
Tabs.Panel = Panel;
// Usage:
<Tabs>
<Tabs.Tab index={0}>Home</Tabs.Tab>
<Tabs.Tab index={1}>Profile</Tabs.Tab>
<Tabs.Panel index={0}>Home content</Tabs.Panel>
<Tabs.Panel index={1}>Profile content</Tabs.Panel>
</Tabs>Praktyczny przykład: Disclosure
Komponent Disclosure ma komponenty potomne Trigger i Panel, które współdzielą stan otwarcia i zamknięcia za pośrednictwem kontekstu.
function Disclosure({ children }) {
const [isOpen, setIsOpen] = useState(false);
return (
<DisclosureContext.Provider value={{ isOpen, setIsOpen }}>
<div>{children}</div>
</DisclosureContext.Provider>
);
}
function Trigger({ children }) {
const { isOpen, setIsOpen } = useContext(DisclosureContext);
return <button onClick={() => setIsOpen(o => !o)}>{children}</button>;
}
function Panel({ children }) {
const { isOpen } = useContext(DisclosureContext);
return isOpen ? <div>{children}</div> : null;
}Hooki jako publiczne API
Należy wyeksportować własny hook, aby użytkownicy mogli tworzyć na jego podstawie własne komponenty.
export function useTabs() {
const ctx = useContext(TabsContext);
if (!ctx) throw new Error('useTabs must be used inside <Tabs>');
return ctx;
}Polimorficzne komponenty złożone
Rodzic może renderować dowolny element za pomocą właściwości as lub wzorca asChild (podejście Radix UI). Dzięki temu komponenty złożone można łączyć z dowolnym kodem JSX.
Bezstylowe wzorce komponentów złożonych
Biblioteki headless (Radix, Headless UI) dostarczają komponenty złożone bez stylowania — logika dostępności jest wbudowana, a stylowanie można dostosować do potrzeb.
Pułapka: inspekcja komponentów potomnych
Starszy wzorzec wykorzystywał React.Children do sprawdzania komponentów potomnych — jest kruchy i podatny na błędy. Do współdzielenia stanu zawsze należy preferować kontekst.
Szybki test
Jak komponenty potomne komunikują się z rodzicem we wzorcu komponentów złożonych?
Podsumowanie: komponenty złożone
Komponenty złożone pozwalają powiązanym częściom działać jako jedna deklaratywna całość. Do współdzielenia stanu należy używać Contextu — Provider znajduje się w rodzicu, a komponenty potomne korzystają z useContext. Podkomponenty należy dołączać jako właściwości statyczne, aby ułatwić ich odnalezienie. Własny hook należy eksportować jako publiczne API. Radix i Headless UI są dobrymi przykładami. Należy preferować kontekst zamiast inspekcji za pomocą Children.
Często zadawane pytania
Czy lekcja „Komponenty złożone z Context” jest bezpłatna?
Tak — pełny tekst „Komponenty złożone z Context” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Frontend Academy, przejdź na CoddyKit PRO. Kurs Frontend Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Komponenty złożone z Context”?
Udostępni Pan/Pani niejawny stan między komponentem nadrzędnym a wyznaczonymi komponentami potomnymi za pomocą Context, modelując interfejsy API takie jak i . Ćwiczysz Frontend Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Frontend Academy?
Nie wymagamy żadnego doświadczenia. Frontend Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 1 z 4.
Ile czasu zajmuje lekcja „Komponenty złożone z Context”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Frontend Academy?
Tak. Każda lekcja Frontend Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Komponenty złożone z Context
- Wzorce Render Props i HOC
- Portale dla modali i podpowiedzi
- Granice błędów