Context, portaluri, error boundaries
Fără prop drilling, randare în alt loc din DOM, erori izolate pe secțiuni.
Actualizat
Ce sunt Context, portalurile și error boundaries
Trei unelte React pentru situații pe care props-urile și state-ul obișnuit nu le rezolvă bine:
| Unealtă | Problema pe care o rezolvă |
|---|---|
| Context | o valoare de care au nevoie multe componente, adânc în arbore, fără props pe fiecare nivel |
| Portal | un element care trebuie randat în altă parte a DOM-ului (modal, tooltip) decât locul din arbore |
| Error boundary | o eroare într-o componentă nu trebuie să strice toată pagina |
Context
Problema — prop drilling: user trece prin 5 componente care nu-l folosesc, doar ca să ajungă la a șasea.
const ThemeContext = createContext<'light' | 'dark'>('light') // valoare implicită
export function ThemeProvider({ children }: { children: React.ReactNode }) {
const [theme, setTheme] = useState<'light' | 'dark'>('light')
return <ThemeContext value={theme}>{children}</ThemeContext> // React 19: direct <Context>
}
function Badge() {
const theme = use(ThemeContext) // sau useContext(ThemeContext)
}| Regulă | Detalii |
|---|---|
| câștigă cel mai apropiat provider de deasupra | poți suprascrie valoarea pentru o secțiune |
fără provider → valoarea implicită din createContext |
|
| schimbarea valorii re-randează toți consumatorii | pune în Context valori schimbate rar |
| obiect nou la fiecare randare = re-randări inutile | useMemo pe valoare sau separi în mai multe contexte |
| în Next, provider-ul e Client Component | îl pui în layout.tsx, învelind children (care rămân Server Components) |
Pentru state global schimbat des → Zustand / Redux.
Portaluri
Un modal randat în interiorul unui card cu overflow: hidden sau într-un stacking context se taie sau apare sub alte elemente. createPortal îl randează în alt nod DOM (de obicei la finalul lui body), dar în arborele React rămâne unde l-ai scris — primește Context, evenimentele urcă la părinții React.
import { createPortal } from 'react-dom'
function Modal({ children }: { children: React.ReactNode }) {
return createPortal(<div className="fixed inset-0 grid place-items-center bg-black/40">{children}</div>, document.body)
}Alternativa modernă, fără portal: elementul nativ <dialog> cu showModal() și Popover API (meniul „Toate temele” din aplicația asta) — ambele se randează în top layer, deasupra a tot, cu focus și Esc gestionate de browser.
Error boundaries
O eroare aruncată în timpul randării unei componente demontează, implicit, toată aplicația. Un error boundary prinde eroarea și afișează un fallback doar pentru secțiunea respectivă.
| Unde | Cum |
|---|---|
| Next.js App Router | fișierul error.tsx într-un segment — vezi Layout-uri și stări |
| React simplu | o clasă cu getDerivedStateFromError, sau librăria react-error-boundary |
Nu prind: erori din event handlers (le prinzi cu try/catch), din cod async din afara randării, din Server Actions (le returnezi ca state).
Pe scurt
- Context = transport fără prop drilling; cel mai apropiat provider câștigă; doar pentru valori schimbate rar.
- Portal = randezi în alt loc din DOM, rămâi în arborele React;
<dialog>și popover ca alternative native. - Error boundary = eroarea strică doar secțiunea; în Next,
error.tsx.