React 19 Flashcards

(15 cards)

1
Q

Quelle est la nouveauté la plus révolutionnaire de React 19 ?

A

Le React Compiler (anciennement React Forget).

Il ajoute automatiquement la mémoïsation à votre code. Plus besoin de :
- useMemo
- useCallback
- memo

Avant (React 18) :

const sorted = useMemo(() => items.sort(), [items]);
const handleClick = useCallback(() => onClick(id), [onClick, id]);
export default memo(MyComponent);

Après (React 19) :

const sorted = items.sort();
const handleClick = () => onClick(id);
export default MyComponent;

Le compiler optimise mieux qu’un humain et ne peut pas oublier !

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

Quel est le mnémonique CAFÉ PLUS pour React 19 ?

A

CAFÉ PLUS (React 19 vous donne un boost !) :

  • C : Compiler - Mémoïsation automatique
  • A : Actions - useActionState, useFormStatus, useOptimistic
  • F : Forwarding simplifié - ref comme prop
  • É : État simplifié - use() pour Promises/Contexts
  • P : Provider simplifié - Context sans .Provider
  • L : Link/Meta natifs - Métadonnées dans les composants
  • U : Utilisabilité - Meilleurs messages d’erreur
  • S : Stylesheets - Gestion native avec precedence

Phrase : “Prenez un CAFÉ PLUS pour coder avec React 19 !”

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

Que retourne useActionState et comment l’utiliser ?

A

useActionState retourne [state, formAction, isPending].

Signature :

const [state, formAction, isPending] = useActionState(
  actionFunction,
  initialState
);

Exemple complet :
```
async function subscribe(prevState, formData) {
const email = formData.get(‘email’);
try {
await api.subscribe(email);
return { success: true, error: null };
} catch (err) {
return { success: false, error: err.message };
}
}

function Form() {
const [state, action, isPending] = useActionState(subscribe, {
success: false,
error: null
});

return (
<form action={action}>
<input name=”email” disabled={isPending} />
<button disabled={isPending}>
{isPending ? ‘Envoi…’ : ‘S\‘inscrire’}
</button>
{state.error && <p>{state.error}</p>}
</form>
);
}
~~~

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

Comment fonctionne le hook use() de React 19 ?

A

use() lit des Promises ou Contexts directement dans le rendu.

Lire une Promise :
```
function UserCard({ userPromise }) {
const user = use(userPromise); // Suspend jusqu’à résolution
return <h1>{user.name}</h1>;
}

// OBLIGATOIRE : Suspense parent
<Suspense fallback={<Spinner></Spinner>}>
<UserCard userPromise={fetchUser(1)} />
</Suspense>
```

Lire un Context (conditionnellement !) :

function Button({ showTheme }) {
  if (showTheme) {
    const theme = use(ThemeContext);  // OK !
    return <button className={theme}>Btn</button>;
  }
  return <button>Default</button>;
}

Différence avec useContext : use() peut être appelé conditionnellement !

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

Comment passer une ref en React 19 sans forwardRef ?

A

ref est maintenant une prop normale !

Avant (React 18) :
```
import { forwardRef } from ‘react’;

const Input = forwardRef(function Input(props, ref) {
return <input ref={ref} {…props} />;
});
```

Après (React 19) :

function Input({ ref, ...props }) {
  return <input ref={ref} {...props} />;
}

Utilisation (identique) :

function Form() {
  const inputRef = useRef(null);
  return <Input ref={inputRef} />;
}

Note : forwardRef sera déprécié dans une future version. Un codemod existe pour migrer.

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

Comment fonctionne useFormStatus ?

A

useFormStatus accède à l’état du formulaire PARENT.

IMPORTANT : Doit être dans un composant ENFANT du form !

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

function SubmitButton() {
const { pending, data, method, action } = useFormStatus();

return (
<button disabled={pending}>
{pending ? ‘Envoi…’ : ‘Envoyer’}
</button>
);
}

function ContactForm() {
return (
<form action={sendMessage}>
<input></input>
<SubmitButton></SubmitButton> {/* Doit être ENFANT du form */}
</form>
);
}
```

Retourne :
- pending : boolean (action en cours)
- data : FormData soumis
- method : ‘get’ ou ‘post’
- action : référence à l’action

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

Comment fonctionne useOptimistic ?

A

useOptimistic affiche un état optimiste pendant une action async.

```
import { useOptimistic } from ‘react’;

function TodoList({ todos, addTodo }) {
const [optimisticTodos, addOptimistic] = useOptimistic(
todos,
(current, newTodo) => […current, { …newTodo, pending: true }]
);

async function handleAdd(formData) {
const title = formData.get(‘title’);

// 1. Affiche immédiatement (optimiste)
addOptimistic({ id: Date.now(), title });

// 2. Puis exécute l'action réelle
await addTodo({ title });   }

return (
<ul>
{optimisticTodos.map(todo => (
<li style={{ opacity: todo.pending ? 0.5 : 1 }}>
{todo.title}
</li>
))}
</ul>
);
}
```

Si l’action échoue : L’état optimiste disparaît automatiquement !

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

Comment utiliser les métadonnées de document en React 19 ?

A

React 19 hoist automatiquement <title>, <meta>, <link> vers <head>.

```
function BlogPost({ post }) {
return (
<article>
{/* Hoistés automatiquement vers <head> */}
<title>{post.title} - Mon Blog</title>
<meta name=”description” content={post.excerpt} />
<meta property=”og:title” content={post.title} />
<link rel=”canonical” href={/posts/${post.slug}} />

  <h1>{post.title}</h1>
  <p>{post.content}</p>
</article>   ); } ```

Avantages :
- Plus besoin de react-helmet
- Fonctionne avec SSR et Suspense
- Gère les doublons automatiquement
- Chaque composant gère ses métadonnées

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 19 ?

```
function UserProfile({ userId }) {
const user = use(
fetch(/api/users/${userId}).then(r => r.json())
);
return <h1>{user.name}</h1>;
}
~~~

A

Problème : Nouvelle Promise à chaque rendu = boucle infinie !

Explication :
1. use() suspend le composant
2. Au re-render, nouvelle Promise créée
3. use() suspend à nouveau
4. Boucle infinie !

Solution 1 : Passer la Promise en prop
```
function UserProfile({ userPromise }) {
const user = use(userPromise);
return <h1>{user.name}</h1>;
}

// Parent crée la Promise une seule fois
<UserProfile userPromise={fetchUser(1)} />
```

Solution 2 : Utiliser un cache
```
const cache = new Map();
function getUser(id) {
if (!cache.has(id)) {
cache.set(id, fetch(/api/users/${id}).then(r => r.json()));
}
return cache.get(id);
}

function UserProfile({ userId }) {
const user = use(getUser(userId));
return <h1>{user.name}</h1>;
}
~~~

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

Comment utiliser Context sans .Provider en React 19 ?

A

React 19 permet de rendre le Context directement !

Avant (React 18) :
```
const ThemeContext = createContext(‘light’);

function App() {
return (
<ThemeContext.Provider>
<Content></Content>
</ThemeContext.Provider>
);
}
```

Après (React 19) :
```
const ThemeContext = createContext(‘light’);

function App() {
return (
<ThemeContext>
<Content></Content>
</ThemeContext>
);
}
```

Note : .Provider sera déprécié dans une future version mais reste fonctionnel pour la compatibilité.

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

Comment fonctionnent les fonctions de cleanup dans les refs ?

A

React 19 : Les refs peuvent retourner une fonction de cleanup !

Avant (React 18) :
```
function Video({ src }) {
const videoRef = useRef(null);

useEffect(() => {
videoRef.current?.play();
return () => {
videoRef.current?.pause();
};
}, []);

return <video ref={videoRef} src={src} />;
}
```

Après (React 19) :
```
function Video({ src }) {
return (
<video
ref={(video) => {
if (video) video.play();

    // Cleanup function !
    return () => {
      if (video) video.pause();
    };
  }}
  src={src}
/>   ); } ```

Avantage : Plus besoin de useEffect + useRef pour des setups/cleanups simples !

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

Quelles sont les APIs de préchargement de React 19 ?

A

Nouvelles fonctions dans react-dom :

```
import {
prefetchDNS,
preconnect,
preload,
preinit
} from ‘react-dom’;

function App() {
// 1. Pré-résoudre le DNS
prefetchDNS(‘https://api.example.com’);

// 2. Établir connexion TCP/TLS
preconnect(‘https://api.example.com’);

// 3. Télécharger sans exécuter
preload(‘/fonts/roboto.woff2’, {
as: ‘font’,
type: ‘font/woff2’
});

// 4. Télécharger ET exécuter/appliquer
preinit(‘/scripts/analytics.js’, { as: ‘script’ });

return <Content></Content>;
}
```

Différences :
- prefetchDNS → DNS seulement
- preconnect → DNS + TCP + TLS
- preload → Télécharge (pas d’exécution)
- preinit → Télécharge + exécute/applique

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

Comment gérer les stylesheets avec precedence en React 19 ?

A

React 19 gère nativement les stylesheets avec priorité.

```
function ProductPage({ product }) {
return (
<>
{/* Haute priorité - bloque le rendu */}
<link></link>

  {/* Priorité moyenne */}
  <link
    rel="stylesheet"
    href="/styles/product.css"
    precedence="medium"
  />

  {/* Basse priorité */}
  <link
    rel="stylesheet"
    href="/styles/reviews.css"
    precedence="low"
  />

  <ProductContent />
</>   ); } ```

precedence contrôle :
- L’ordre d’insertion dans <head>
- Le groupement des stylesheets
- Évite les problèmes de spécificité CSS

React déduplique automatiquement les stylesheets identiques !

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

Quelle est la différence entre useActionState et useFormStatus ?

A

Tableau comparatif :

useActionState - Définit et gère l’action :
```
const [state, action, isPending] = useActionState(
myAction,
initialState
);

return <form action={action}>…</form>;
```

useFormStatus - Lit l’état du form parent :
```
function SubmitBtn() {
const { pending } = useFormStatus();
return <button disabled={pending}>Submit</button>;
}

// DOIT être enfant du form
<form action={…}>

<SubmitBtn></SubmitBtn>

</form>
~~~

Aspect | useActionState | useFormStatus |
|——–|—————-|—————|
| Import | react | react-dom |
| Retourne | [state, action, isPending] | { pending, data, method } |
| Usage | Définir l’action | Lire l’état du form |
| Placement | N’importe où | ENFANT du form |

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

Comment migrer un composant React 18 vers React 19 avec les Actions ?

A

Migration d’un formulaire classique vers Actions :

Avant (React 18) :
```
function Form() {
const [value, setValue] = useState(‘’);
const [isPending, setIsPending] = useState(false);
const [error, setError] = useState(null);

async function handleSubmit(e) {
e.preventDefault();
setIsPending(true);
try {
await submitData(value);
} catch (err) {
setError(err.message);
} finally {
setIsPending(false);
}
}

return (
<form onSubmit={handleSubmit}>
<input value={value} onChange={e => setValue(e.target.value)} />
<button disabled={isPending}>Submit</button>
</form>
);
}
```

Après (React 19) :
```
async function submitAction(prev, formData) {
try {
await submitData(formData.get(‘value’));
return { error: null };
} catch (err) {
return { error: err.message };
}
}

function Form() {
const [state, action, isPending] = useActionState(submitAction, { error: null });

return (
<form action={action}>
<input></input>
<button disabled={isPending}>Submit</button>
{state.error && <p>{state.error}</p>}
</form>
);
}
~~~

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