1. Comment optimiser les performances de rendu dans React ?
React.memo : evite le re-render d'un composant si ses props n'ont pas change (comparaison shallow). useMemo : memorise le resultat d'un calcul couteux, recalcule seulement quand les dependances changent. useCallback : memorise une reference de fonction pour eviter les re-renders des composants enfants. Virtualisation : react-window ou react-virtuoso pour les grandes listes (ne rend que les elements visibles). Code splitting : React.lazy + Suspense pour le chargement dynamique des composants. Keys stables : ne jamais utiliser l'index comme key dans les listes dynamiques. Profiler : React DevTools Profiler pour identifier les re-renders inutiles. Attention : ne pas optimiser prematureement, mesurer d'abord.
2. Expliquez les patterns de gestion d'etat avances en React.
Contexte + useReducer : alternative legere a Redux pour l'etat partage. Limiter la taille des contextes pour eviter les re-renders (separer les contextes par domaine). Redux Toolkit : Redux moderne avec createSlice, createAsyncThunk, RTK Query pour le data fetching. Zustand : store minimaliste, API simple, pas de boilerplate. Jotai/Recoil : etat atomique, chaque atome est independant, re-renders granulaires. TanStack Query (React Query) : gestion d'etat serveur (cache, revalidation, optimistic updates). Pattern recommande : TanStack Query pour l'etat serveur, Zustand ou Context pour l'etat client UI. Eviter de mettre l'etat serveur dans Redux (duplication, stale data).
3. Comment fonctionne le Server-Side Rendering (SSR) avec React ?
Le SSR genere le HTML sur le serveur pour chaque requete. Avantages : meilleur SEO, First Contentful Paint plus rapide, contenu visible avant le chargement JS. L'hydration attache les event handlers au HTML statique cote client. Next.js simplifie le SSR avec getServerSideProps (SSR par requete) et getStaticProps (SSG au build). React Server Components (RSC) dans Next.js App Router : composants executes uniquement sur le serveur, zero JS client, acces direct aux donnees. Streaming SSR avec Suspense : envoie le HTML progressivement, ameliore le Time To First Byte. Trade-offs : complexite serveur, latence serveur, cout d'hydration. SSG preferable quand le contenu ne change pas a chaque requete.
4. Qu'est-ce que les React Server Components et comment les utiliser ?
Les RSC sont des composants qui s'executent uniquement sur le serveur. Pas de state, pas d'effects, pas d'event handlers. Avantages : acces direct a la base de donnees et au filesystem, zero bundle JS pour ces composants, streaming automatique. Les Client Components (marques avec 'use client') gerent l'interactivite. Architecture : les Server Components en parents, les Client Components en feuilles pour l'interactivite. Un Server Component peut passer des props serialisables a un Client Component. Un Client Component ne peut pas importer un Server Component directement (mais peut le recevoir via children). Pattern : layouts et data fetching en Server Components, formulaires et interactions en Client Components.
5. Comment gerer les formulaires complexes en React ?
Controlled components : l'etat React controle les valeurs des champs (onChange + state). Recommande pour la plupart des cas. React Hook Form : minimal re-renders, validation performante, integration avec Zod/Yup pour la validation de schema. Avantages : register() pour l'enregistrement des champs, handleSubmit pour la soumission, formState pour les erreurs et l'etat de soumission. Validation : schema-based avec Zod (type-safe, inference TypeScript). Dynamic forms : useFieldArray pour les champs repetes. Optimistic UI : mettre a jour l'interface avant la confirmation serveur avec revert en cas d'erreur. Server Actions (Next.js) : soumettre les formulaires directement au serveur sans API endpoint explicite.
6. Expliquez les hooks personnalises et leurs patterns avances.
Les custom hooks encapsulent la logique reutilisable avec les hooks React. Conventions : prefixer par use, retourner un tuple ou un objet. Patterns utiles : useDebounce (retarder une valeur), useMediaQuery (responsive), usePrevious (valeur precedente), useIntersectionObserver (lazy loading), useLocalStorage (persistence). Composition : combiner plusieurs hooks dans un hook de plus haut niveau. Hook factories : fonctions qui retournent des hooks configures. Regles : ne pas appeler de hooks conditionnellement, les hooks doivent etre purs (pas d'effets de bord dans le render). useEffect cleanup : toujours retourner une fonction de nettoyage pour les subscriptions, timers, et event listeners pour eviter les memory leaks.
7. Comment implementer l'authentification dans une application React ?
Architecture : JWT stocke dans un httpOnly cookie (plus securise que localStorage contre XSS). Le serveur set le cookie, le navigateur l'envoie automatiquement. Context d'authentification : AuthProvider wrappant l'application, exposant user, login(), logout(), isAuthenticated. Protected routes : composant HigherOrder ou layout verifiant l'authentification, redirigeant vers /login si non authentifie. Token refresh : intercepteur Axios/fetch qui rafraichit le token automatiquement avant expiration. RBAC : role-based access control avec un hook usePermission. Avec Next.js : middleware pour la protection cote serveur, getServerSideProps pour la verification pre-render. OAuth : utiliser des bibliotheques comme NextAuth.js (Auth.js) pour l'integration avec les providers.
8. Comment tester les composants React efficacement ?
Testing Library : philosophie "test as user" (selectionner par role, texte, label, pas par implementation). Unit tests : composants isoles avec render(), screen queries, fireEvent/userEvent. Integration tests : plusieurs composants ensemble, tester les flux utilisateur complets. Mock : MSW (Mock Service Worker) pour intercepter les requetes HTTP au niveau du reseau (pas de mock des modules). Async testing : waitFor et findBy pour les operations asynchrones. Snapshot tests : utiles pour les composants statiques, fragiles pour les composants dynamiques. Custom render : wrapper avec les providers (Router, Query, Theme) pour eviter la repetition. Couverture : prioriser les chemins critiques (formulaires, navigation, etats d'erreur) plutot qu'un pourcentage arbitraire.
9. Qu'est-ce que les patterns de composition en React ?
Compound Components : composants qui fonctionnent ensemble (Tabs, Tab.List, Tab.Panel) partageant un etat implicite via Context. Render Props : passer une fonction comme prop qui recoit des donnees et retourne du JSX (pattern plus rare depuis les hooks). Higher-Order Components (HOC) : fonction qui prend un composant et retourne un composant enrichi (withAuth, withTheme). Moins utilise depuis les hooks. Slots pattern : props comme header, footer, sidebar pour injecter du contenu a des emplacements specifiques. Headless components : logique sans UI (useCombobox de Downshift), l'utilisateur fournit le rendu. Le pattern moderne prefere : custom hooks pour la logique, composants composes pour l'UI.
10. Comment gerer les erreurs et le monitoring dans une application React ?
Error Boundaries : classes React avec componentDidCatch et getDerivedStateFromError. Capturent les erreurs de rendu des composants enfants et affichent une UI de fallback. Ne capturent pas : event handlers, code asynchrone, SSR, erreurs dans le boundary lui-meme. Granularite : plusieurs error boundaries a differents niveaux (page, section, composant). Error reporting : Sentry, Bugsnag ou DataDog RUM pour capturer et agreger les erreurs en production avec stack traces, contexte utilisateur, et breadcrumbs. Retry pattern : bouton "Reessayer" dans le fallback qui reset le boundary (key change). Suspense : gestion native du loading state, combinable avec error boundaries pour une UX coherente loading/error/success.