React 18 Flashcards

(15 cards)

1
Q

Quelle est la nouvelle API obligatoire pour activer les fonctionnalités de React 18 ?

A

createRoot est la nouvelle API obligatoire.

Avant (React 17) :

import ReactDOM from 'react-dom';
ReactDOM.render(<App />, document.getElementById('root'));

Après (React 18) :

import { createRoot } from 'react-dom/client';
const root = createRoot(document.getElementById('root'));
root.render(<App />);

Pourquoi : Sans createRoot, vous restez en mode legacy et perdez TOUTES les nouvelles fonctionnalités (concurrent rendering, transitions, etc.).

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

Qu’est-ce que le Concurrent Rendering de React 18 ?

A

Le Concurrent Rendering permet à React d’interrompre un rendu en cours pour traiter quelque chose de plus urgent, puis de reprendre là où il s’était arrêté.

Analogie : Un serveur de restaurant qui peut interrompre une commande pour gérer une urgence, puis revenir à sa tâche.

Avantage : L’interface reste fluide même pendant des rendus coûteux.

Activation : Automatique avec createRoot, mais nécessite useTransition ou useDeferredValue pour marquer les mises à jour non-urgentes.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

Quel est le mnémonique CATBUS pour retenir les nouveautés de React 18 ?

A

CATBUS (comme le chat-bus de Totoro) :

  • C : Concurrent Rendering - React peut interrompre les rendus
  • A : Automatic Batching - Groupement automatique partout
  • T : Transitions - useTransition et startTransition
  • B : Better Suspense - SSR avec streaming
  • U : useId et nouveaux hooks
  • S : Strict Mode amélioré - Double montage

Phrase : “Le CATBUS de React 18 vous transporte vers des interfaces plus fluides !”

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

Qu’est-ce que l’Automatic Batching de React 18 ?

A

L’Automatic Batching regroupe automatiquement TOUTES les mises à jour de state en un seul re-rendu.

Avant React 18 :

async function handleSubmit() {
  await saveData();
  setCount(c => c + 1);  // Re-rendu 1
  setFlag(f => !f);       // Re-rendu 2
}

Avec React 18 :

async function handleSubmit() {
  await saveData();
  setCount(c => c + 1);  // Groupé
  setFlag(f => !f);       // 1 seul re-rendu !
}

Fonctionne partout : setTimeout, fetch, Promises, event listeners…

Opt-out : Utilisez flushSync() si vous avez besoin de forcer un re-rendu immédiat.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

Que retourne useTransition et comment l’utiliser ?

A

useTransition retourne un tableau [isPending, startTransition].

isPending : booléen indiquant si une transition est en cours
startTransition : fonction pour envelopper les mises à jour non-urgentes

Exemple :
```
const [isPending, startTransition] = useTransition();

function handleClick() {
// URGENT : input réactif
setQuery(value);

// NON-URGENT : peut attendre
startTransition(() => {
setFilteredResults(filter(value));
});
}

return (
<>
{isPending && <Spinner></Spinner>}
<Results></Results>
</>
);
```

Utiliser quand : Vous contrôlez le setState qui cause un rendu lent.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

Quelle est la différence entre useTransition et useDeferredValue ?

A

Tableau comparatif :

useTransition :

const [isPending, startTransition] = useTransition();
startTransition(() => setState(value));

useDeferredValue :

const deferredQuery = useDeferredValue(props.query);

Règle : useTransition quand vous CONTRÔLEZ, useDeferredValue quand vous RECEVEZ.

Aspect | useTransition | useDeferredValue |
|——–|—————|——————|
| Contrôle | Vous contrôlez le setState | Vous recevez une valeur |
| Retour | [isPending, startTransition] | valeur différée |
| Usage | Envelopper un setState | Différer une prop |

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

Que va afficher ce code en Strict Mode React 18 ?

```
function App() {
useEffect(() => {
console.log(‘monté’);
return () => console.log(‘démonté’);
}, []);
return <div>Hello</div>;
}
~~~

A

Résultat en Strict Mode :

monté
démonté
monté

Explication : Le Strict Mode de React 18 simule un démontage/remontage pour vérifier que vos effets sont correctement nettoyés.

Pourquoi : Prépare aux futures fonctionnalités comme l’Offscreen API où les composants peuvent être “mis en pause”.

Important : Ce comportement n’existe qu’en développement, pas en production.

Leçon : Toujours inclure une fonction de cleanup dans useEffect !

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

À quoi sert useId et quand NE PAS l’utiliser ?

A

useId génère des IDs uniques et stables pour l’accessibilité.

Utiliser pour :

function FormField({ label }) {
  const id = useId();
  return (
    <>
      <label htmlFor={id}>{label}</label>
      <input id={id} />
    </>
  );
}

NE JAMAIS utiliser pour les clés de liste !

❌ Mauvais :

{items.map((item, i) => (
  <li key={`${useId()}-${i}`}>{item}</li>  // INTERDIT
))}

✅ Correct :

{items.map(item => (
  <li key={item.id}>{item.name}</li>
))}

Pourquoi useId : Stable entre serveur et client (SSR compatible).

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Quel est le problème avec ce code React 18 ?

```
function Search({ query }) {
const [isPending, startTransition] = useTransition();

startTransition(() => {
// query est une prop, pas un state local
});
}
~~~

A

Problème : On ne peut pas “différer” une prop avec useTransition !

Explication : useTransition est fait pour envelopper vos propres setState. Si vous recevez une valeur en props, utilisez useDeferredValue.

Solution :
```
function Search({ query }) {
// Différer la VALEUR reçue
const deferredQuery = useDeferredValue(query);

return <Results query={deferredQuery} />;
}
```

Règle :
- useTransition : quand VOUS contrôlez le setState
- useDeferredValue : quand vous RECEVEZ une valeur

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

Comment fonctionne l’ordre d’exécution des effets en React 18 ?

A

Ordre d’exécution :

  1. useInsertionEffect - Avant les mutations DOM (CSS-in-JS)
  2. Mutations DOM - React modifie le DOM
  3. useLayoutEffect - Après mutations, AVANT le paint
  4. Paint - Le navigateur affiche
  5. useEffect - Après le paint (asynchrone)

Exemple :
```
useInsertionEffect(() => {
// 1. Injecter les styles
});

useLayoutEffect(() => {
// 3. Mesurer le DOM
});

useEffect(() => {
// 5. Effets de bord (fetch, subscriptions)
});
```

useInsertionEffect : Réservé aux bibliothèques CSS-in-JS (styled-components, Emotion).

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

Comment migrer de React 17 à React 18 en 3 étapes ?

A

Migration minimale en 3 étapes :

1. Mettre à jour les packages :

npm install react@18 react-dom@18

2. Modifier index.js :
```
// Avant
import ReactDOM from ‘react-dom’;
ReactDOM.render(<App></App>, document.getElementById(‘root’));

// Après
import { createRoot } from ‘react-dom/client’;
const root = createRoot(document.getElementById(‘root’));
root.render(<App></App>);
```

3. Vérifier les effets : S’assurer que tous les useEffect ont une fonction de cleanup.

Bonus automatique : Vous bénéficiez immédiatement de l’Automatic Batching !

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

À quoi sert useSyncExternalStore ?

A

useSyncExternalStore permet de s’abonner à des stores externes de manière compatible avec le concurrent rendering.

Destiné aux auteurs de bibliothèques (Redux, Zustand, etc.)

Exemple :

function useWindowWidth() {
  return useSyncExternalStore(
    // subscribe
    (callback) => {
      window.addEventListener('resize', callback);
      return () => window.removeEventListener('resize', callback);
    },
    // getSnapshot (client)
    () => window.innerWidth,
    // getServerSnapshot (SSR)
    () => 1024
  );
}

3 paramètres :
1. Fonction d’abonnement
2. Getter de la valeur (client)
3. Getter de la valeur (serveur, optionnel)

Vous n’utiliserez probablement jamais ce hook directement.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

Quelles sont les améliorations de Suspense dans React 18 ?

A

Suspense amélioré en React 18 :

1. SSR avec Streaming :
Le HTML est envoyé progressivement au navigateur.

2. Hydratation Sélective :
React hydrate les composants par ordre de priorité.

3. Interruption :
Si l’utilisateur interagit avec un composant non-hydraté, React le priorise.

Exemple :
```
<Suspense fallback={<Spinner></Spinner>}>

<SlowComponent></SlowComponent>

</Suspense>

<Suspense fallback={<CommentsSkeleton></CommentsSkeleton>}>

<Comments></Comments>

</Suspense>
```

Avantage : L’utilisateur peut voir et interagir avec les parties rapides pendant que les parties lentes chargent.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

Comment désactiver le batching automatique si nécessaire ?

A

Utilisez flushSync pour forcer des re-rendus séparés.

```
import { flushSync } from ‘react-dom’;

function handleClick() {
flushSync(() => {
setCount(c => c + 1);
});
// DOM mis à jour ici

flushSync(() => {
setFlag(f => !f);
});
// DOM mis à jour ici aussi
}
```

Cas d’usage rare :
- Mesurer le DOM entre deux mises à jour
- Intégration avec du code legacy
- Animations spécifiques

Attention : flushSync nuit aux performances. Évitez-le sauf si absolument nécessaire.

99% du temps : Laissez le batching automatique faire son travail !

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

Comment créer un champ de recherche optimisé avec les Transitions ?

A

Pattern complet de recherche avec Transitions :

```
import { useState, useTransition } from ‘react’;

function SearchList({ items }) {
const [query, setQuery] = useState(‘’);
const [filtered, setFiltered] = useState(items);
const [isPending, startTransition] = useTransition();

function handleSearch(e) {
const value = e.target.value;

// URGENT : input réactif
setQuery(value);

// NON-URGENT : filtrage
startTransition(() => {
  setFiltered(items.filter(item =>
    item.includes(value)
  ));
});   }

return (
<>
<input value={query} onChange={handleSearch} />
{isPending && <span>Recherche…</span>}
<ul style={{ opacity: isPending ? 0.7 : 1 }}>
{filtered.map(item => <li key={item}>{item}</li>)}
</ul>
</>
);
}
```

Points clés :
- 2 states : un urgent (query), un différé (filtered)
- isPending pour feedback visuel
- Opacité réduite pendant la transition

How well did you know this?
1
Not at all
2
3
4
5
Perfectly