Préparation d'entretien 100% Gratuit angularforall.com

Entretien React Senior : performance et testing

React Senior Quiz-React-Senior Memoization Usememo Usecallback Code-Splitting Lazy-Loading React-Testing-Library Patterns-React Architecture-React Questions-Entretien-React-Senior Qcm-React-Avance Front-End
Sénior 🔀 Mixte 20 questions ⏱ 15 min
📝

Entretien React Senior : performance et testing

20 questions React avancées : memoization, useMemo, useCallback, code splitting, lazy loading, testing avec RTL, patterns avancés et architecture pour React Senior.

20 questions ⏱ ~15 min Niveau Sénior

Partager

Banque de révision : les 20 questions corrigées

Voici l'intégralité des 20 questions de « Entretien React Senior : performance et testing », chacune avec sa bonne réponse et son explication. Le quiz interactif ci-dessus en tire une sélection aléatoire à chaque tentative — utilisez cette liste complète pour réviser.

  • Le mode concurrent peut interrompre et reprendre le rendu, prioriser les mises à jour urgentes (bonne réponse)
  • Le mode concurrent est juste plus rapide
  • Il n'y a pas de différence
  • Le mode concurrent supprime le Virtual DOM
Explication : Le rendu concurrent permet à React de préparer plusieurs versions de l'UI en mémoire, d'interrompre un rendu long pour gérer une interaction utilisateur urgente, et de reprendre le rendu interrompu. Les fonctionnalités comme Suspense, useTransition et useDeferredValue exploitent ce mécanisme.
Le mode concurrent est activé automatiquement avec createRoot() dans React 18+. render() reste en mode legacy.

  • Permettre l'exécution de composants côté serveur pour réduire la taille du bundle client (bonne réponse)
  • Remplacer les API REST
  • Améliorer le CSS des composants
  • Rendre React plus rapide que Vue
Explication : Les RSC permettent d'exécuter des composants exclusivement côté serveur. Ces composants peuvent accéder directement aux bases de données, au système de fichiers, sans exposer de code au client, et ne sont pas inclus dans le bundle JavaScript.
Distinction clé : RSC ≠ SSR. Le SSR génère du HTML initial ; les RSC peuvent être exécutés à la demande pour charger des données sans envoyer de JS client.

  • Il permet de marquer certaines mises à jour comme non urgentes pour ne pas bloquer l'UI (bonne réponse)
  • Il crée des animations de transition CSS
  • Il gère le lazy loading
  • Il remplace useEffect
Explication : useTransition retourne [isPending, startTransition]. Les mises à jour dans startTransition sont marquées comme non urgentes : React peut les interrompre pour gérer des interactions utilisateur plus prioritaires (ex: taper dans un input).
Utilisez startTransition autour des mises à jour coûteuses (filtrage d'une longue liste) pendant que l'utilisateur tape, pour que l'input reste fluide.

  • Déférer une valeur pour ne pas bloquer le rendu urgent, utile quand on ne contrôle pas la source (bonne réponse)
  • Ajouter un délai aux requêtes API
  • Mettre en cache des valeurs
  • Créer des variables asynchrones
Explication : useDeferredValue(valeur) retourne une version "déférée" de la valeur qui ne se mettra à jour qu'une fois les rendus urgents terminés. Contrairement à useTransition, il ne nécessite pas de contrôler le setState (utile quand la valeur vient d'une source externe).
À utiliser quand vous recevez des données d'une bibliothèque tierce et que vous voulez éviter que ses mises à jour ne bloquent votre UI.

  • React compare l'arbre Virtual DOM précédent et suivant (diffing) et met à jour uniquement les nœuds modifiés (bonne réponse)
  • React reconstruit tout le DOM à chaque mise à jour
  • React utilise un système de dirty checking comme Angular.js
  • React ne met à jour que le composant qui a changé
Explication : La réconciliation est l'algorithme de diffing de React : il compare deux arbres Virtual DOM, identifie les différences (type, props, children), et génère un patch minimal à appliquer au DOM réel. L'algorithme O(n) repose sur deux hypothèses : éléments de type différent produisent des arbres différents, et les clés (keys) stabilisent l'identité.
Comprendre la réconciliation aide à optimiser : une clé stable empêche la recréation inutile, et changer le type d'un élément force le démontage/remontage complet.

  • Plusieurs mises à jour d'état sont groupées en un seul re-rendu, même dans les promesses et setTimeout (bonne réponse)
  • Les rendus sont mis en cache automatiquement
  • Les composants sont chargés par lots depuis le serveur
  • C'est un nouveau type de state management
Explication : Avant React 18, le batching ne fonctionnait que dans les gestionnaires d'événements React. Avec le batching automatique, les mises à jour dans les promesses, setTimeout, et événements natifs sont aussi groupées, réduisant le nombre de re-rendus.
Pour échapper au batching (cas rare), utilisez flushSync(). Cela force une mise à jour synchrone immédiate du DOM.

  • Un pattern où plusieurs composants partagent un état implicite via Context pour une API déclarative flexible (bonne réponse)
  • Un pattern où tous les composants sont fusionnés en un seul
  • Un pattern de composition chimique
  • Un pattern pour les animations
Explication : Le pattern Compound Components permet de créer un ensemble de composants qui partagent un état interne et fonctionnent ensemble. Exemple : <Select> contient <Select.Option>. L'état est partagé via Context. Cela offre une API déclarative et flexible.
Les bibliothèques UI comme Mantine, Radix UI, et Headless UI utilisent massivement ce pattern. Il évite d'avoir à passer toutes les props à travers un seul composant monolithique.

  • React.FC/React.FunctionComponent avec des génériques pour typer les props et les retours (bonne réponse)
  • TypeScript n'est pas compatible avec React
  • Il faut utiliser PropTypes à la place
  • Les types sont automatiquement inférés
Explication : TypeScript s'intègre avec React via des types utilitaires : React.FC<Props>, React.ReactNode pour les children, React.ComponentProps<typeof Composant> pour extraire les props, React.CSSProperties pour les styles, etc.
Évitez React.FC qui ajoute implicitement children. Préférez typer les props directement : function Comp({ name }: { name: string }).

  • Permettre au consommateur d'un composant de contrôler comment l'état est mis à jour en passant son propre reducer (bonne réponse)
  • Un reducer qui gère tout l'état de l'application
  • Un pattern Redux
  • Un hook React
Explication : Le pattern State Reducer donne le contrôle total du reducer interne d'un composant à son utilisateur via une prop. L'utilisateur peut intercepter et modifier les actions. C'est une inversion de contrôle puissante, utilisée dans Downshift.
Ce pattern est avancé : combinez-le avec un reducer par défaut et utilisez la composition de reducers pour ne pas rompre le comportement par défaut.

  • Les composants serveur ne sont pas interactifs ; l'interactivité est isolée dans des composants client (use client) (bonne réponse)
  • Ils utilisent WebSockets pour l'interactivité
  • Ils deviennent automatiquement interactifs
  • Ils utilisent AJAX pour chaque clic
Explication : Dans l'App Router Next.js, les composants sont "serveur" par défaut (pas d'état, pas d'événements). Pour ajouter de l'interactivité, on isole cette partie dans un composant "client" marqué avec "use client" en haut du fichier.
Bonne pratique : gardez la structure et le chargement de données côté serveur, et islez l'interactivité dans des composants client feuilles.

  • Flux a plusieurs stores ; Redux a un store unique avec un reducer racine (bonne réponse)
  • Flux est plus rapide que Redux
  • Ils sont identiques
  • Redux n'a aucun lien avec Flux
Explication : Flux (Facebook) propose un flux unidirectionnel avec plusieurs stores. Redux s'inspire de Flux mais simplifie : un seul store, un reducer racine (fonction pure), et pas de dispatcher multiple. Redux Toolkit modernise encore avec des slices et Immer pour l'immutabilité.
Redux suit trois principes : source unique de vérité, état en lecture seule, modifications via des fonctions pures (reducers).

  • Utiliser React.memo + useCallback + useMemo de manière combinée et stable (bonne réponse)
  • N'utiliser que des composants classes
  • Placer tout dans useEffect
  • Utiliser useRef pour tout l'état
Explication : Pour éviter totalement un re-rendu, il faut garantir l'égalité référentielle de toutes les props : React.memo pour le composant enfant, useCallback pour les fonctions, useMemo pour les objets/tableaux. Si toutes les références sont stables, React.memo bloquera le re-rendu.
Dans la pratique, le profilage (React DevTools Profiler) doit guider l'optimisation. Ne pas optimiser prématurément.

  • Un pattern d'injection de dépendances utilisant Context pour fournir des données/services à tout l'arbre (bonne réponse)
  • Un composant qui fournit des données depuis une API
  • Un nouveau hook React 18
  • Un pattern de CSS-in-JS
Explication : Le pattern Provider utilise l'API Context pour injecter des données ou services accessibles par tous les descendants sans prop drilling. Correctement utilisé : séparez la logique d'état du Provider (souvent avec useReducer) et exposez un hook consommateur (useMonContext()).
Évitez de mettre des valeurs qui changent fréquemment dans un Provider large : cela cause des re-rendus massifs. Scindez les contextes par domaine de responsabilité.

  • Le serveur envoie le HTML par morceaux, remplaçant les fallbacks Suspense au fur et à mesure (bonne réponse)
  • Le serveur envoie tout le HTML d'un coup puis hydrate
  • Le streaming ne fonctionne qu'avec les WebSockets
  • C'est identique au SSR traditionnel
Explication : Avec renderToPipeableStream, le serveur peut envoyer le HTML progressivement. Les parties enveloppées dans <Suspense> sont remplacées par leurs fallbacks, puis le contenu réel est streamé et remplace le fallback quand il est prêt. L'hydratation est aussi progressive.
Priorisez le contenu important (au-dessus de la ligne de flottaison) et entourez le reste de Suspense pour un LCP (Largest Contentful Paint) optimal.

  • Séparer la logique et le comportement de l'interface visuelle, en laissant le style au développeur (bonne réponse)
  • Des composants sans tête (head) HTML
  • Une librairie spécifique
  • Un type de test unitaire
Explication : Les composants Headless (comme Headless UI, Radix UI, TanStack Table) fournissent toute la logique (accessibilité, état, interactions) sans imposer de design. Le développeur contrôle entièrement le rendu via des render props ou des hooks.
Cette approche est devenue populaire car elle permet de créer des design systems sur mesure tout en bénéficiant de logiques complexes (combobox, menu, table de données) testées et accessibles.

  • Zustand utilise un store minimaliste basé sur des hooks, sans providers, sans reducers obligatoires (bonne réponse)
  • Zustand est plus lent que Redux
  • Zustand est une copie exacte de Redux
  • Zustand remplace React Context
Explication : Zustand est un state manager léger qui utilise des fonctions pour créer des stores accessibles via un hook simple. Contrairement à Redux : pas de Provider, pas de reducers obligatoires, support natif des actions asynchrones, pas de boilerplate.
Zustand sélectionne automatiquement une partie du state et ne re-rend que si cette partie change, grâce à des sélecteurs optionnels.

  • Permettre à un parent d'accéder au nœud DOM d'un composant enfant ; cas avancé : refs impératives avec useImperativeHandle (bonne réponse)
  • Une méthode pour optimiser les refs
  • Un hook pour créer des refs
  • Un type de memoïsation
Explication : React.forwardRef permet de passer une ref à travers un composant enfant. Avec useImperativeHandle, l'enfant peut exposer une API impérative personnalisée au parent (ex: focus(), reset(), scrollToTop()).
À utiliser avec parcimonie : préférez les solutions déclaratives. Les refs impératives sont utiles pour des intégrations avec des bibliothèques non-React ou des animations complexes.

  • SSR génère le HTML à chaque requête ; SSG génère le HTML au build, une fois pour toutes (bonne réponse)
  • SSG est plus lent que SSR
  • SSR ne fonctionne qu'avec Next.js
  • Il n'y a pas de différence
Explication : SSR (Server-Side Rendering) : le HTML est généré dynamiquement à chaque requête sur le serveur. SSG (Static Site Generation) : le HTML est généré au build et servi comme fichier statique. ISR (Incremental Static Regeneration) est un hybride : régénération périodique.
SSG pour les pages qui changent rarement (blog, docs). SSR pour les contenus dynamiques par utilisateur (dashboard). ISR pour les deux cas avec un délai de fraîcheur configurable.

  • Mettre à jour uniquement les parties de l'UI liées à une donnée modifiée, sans diffing d'arbre complet (bonne réponse)
  • Une version plus détaillée du Virtual DOM
  • Un nouveau hook React 18
  • Une librairie de state management
Explication : La réactivité fine-grained (SolidJS, Preact Signals, Voby) suit les dépendances au niveau atomique : quand une valeur change, seuls les endroits exacts qui l'utilisent sont mis à jour. Pas de Virtual DOM ni de diffing d'arbre : c'est plus performant. React explore ce concept avec des propositions comme React Forget (compilateur).
Cette différence architecturale explique pourquoi SolidJS est souvent plus rapide que React, bien que React compense par un écosystème plus mature.

  • Un compilateur qui automatise useMemo/useCallback en analysant le code pour une performance optimale sans intervention du développeur (bonne réponse)
  • Un compilateur qui transforme React en Vue
  • Un outil de build plus rapide
  • Un nouveau type de composant
Explication : React Forget (en développement) est un compilateur qui analyse automatiquement le code pour déterminer ce qui doit être mémorisé. Son but : éliminer le besoin d'utiliser manuellement useMemo, useCallback, et React.memo pour les performances.
Forget n'est pas encore stable, mais il représente la direction future de React : laisser le compilateur gérer les optimisations pour que le développeur se concentre sur la logique métier.