use
est une API React qui vous permet de lire la valeur d’une ressource telle qu’une promesse ou un contexte.
const value = use(resource);
Référence
use(resource)
Appelez use
dans votre composant pour lire la valeur d’une ressource telle qu’une promesse ou un contexte.
import { use } from 'react';
function MessageComponent({ messagePromise }) {
const message = use(messagePromise);
const theme = use(ThemeContext);
// ...
Contrairement aux Hooks React, use
peut être appelée au sein de boucles ou d’instructions conditionnelles telles que if
. En revanche, comme pour les Hooks React, toute fonction appelant use
doit être un composant ou un Hook.
Lorsqu’elle est appelée avec une promesse, l’API use
s’intègre avec Suspense
et les périmètres d’erreurs. Le composant appelant suspend tant que la promesse passée à use
est en attente. Si le composant qui appelle use
est enrobé dans un périmètre Suspense, l’UI de secours est affichée. Une fois la promesse accomplie, cette UI est remplacée par le rendu des composants en utilisant les données renvoyées par le Hook use
. Si la promesse renvoyée par use
est rejetée, l’UI de secours du périmètre d’erreur le plus proche est affichée.
Voir d’autres exemples plus bas.
Paramètres
resource
: c’est la source de données depuis laquelle vous voulez lire une valeur. Une ressource peut être une promesse ou un contexte.
Valeur renvoyée
L’API use
renvoie la valeur lue depuis la ressource, telle que la valeur accomplie d’une promesse ou la valeur actuelle d’un contexte.
Limitations
- L’API
use
doit être appelée à l’intérieur d’un composant ou d’un Hook. - Lorsque vous récupérez des données dans un Composant Serveur, privilégiez
async
etawait
plutôt queuse
.async
etawait
reprennent le rendu à partir du point oùawait
avait été invoqué, alors queuse
refait un rendu du composant une fois la donnée obtenue. - Privilégiez la création de promesses dans les Composants Serveur et leur passage aux Composants Client, plutôt que de créer des promesses dans les Composants Client. Les promesses créées dans les Composants Client sont recréées à chaque rendu. Les promesses transmises d’un Composant Serveur à un Component Client ne changent pas d’un rendu à l’autre. Consultez cet exemple.
Utilisation
Lire un contexte avec use
Quand un contexte est passé à use
, ce dernier fonctionne de la même façon que useContext
. Alors que useContext
doit être appelé à la racine de votre composant, use
peut être appelé à l’intérieur de conditions telles que if
ou de boucles telles que for
. use
est préférable à useContext
parce qu’il est plus flexible.
import { use } from 'react';
function Button() {
const theme = use(ThemeContext);
// ...
use
renvoie la valeur de contexte pour le contexte que vous avez transmis. Pour déterminer la valeur du contexte, React remonte l’arbre des composants pour trouver le fournisseur de contexte parent le plus proche pour ce contexte.
Pour transmettre un contexte à un Button
, enrobez ce bouton ou l’un de ses parents dans le fournisseur de contexte adéquat.
function MyPage() {
return (
<ThemeContext.Provider value="dark">
<Form />
</ThemeContext.Provider>
);
}
function Form() {
// ... rendu des boutons ici ...
}
Peu importe le nombre de couches de composants qu’il y a entre le fournisseur et le Button
. Quand un Button
appelle use(ThemeContext)
, il recevra la valeur "dark"
, quelle que soit sa position au sein du Form
.
Contrairement à useContext
, use
peut être appelé dans les blocs conditionnels et les boucles, comme par exemple un if
.
function HorizontalRule({ show }) {
if (show) {
const theme = use(ThemeContext);
return <hr className={theme} />;
}
return false;
}
use
est appelé à l’intérieur d’une instruction if
, ce qui vous permet de ne lire des valeurs de contextes que sous certaines conditions.
import { createContext, use } from 'react'; const ThemeContext = createContext(null); export default function MyApp() { return ( <ThemeContext.Provider value="dark"> <Form /> </ThemeContext.Provider> ) } function Form() { return ( <Panel title="Bienvenue"> <Button show={true}>Inscription</Button> <Button show={false}>Connexion</Button> </Panel> ); } function Panel({ title, children }) { const theme = use(ThemeContext); const className = 'panel-' + theme; return ( <section className={className}> <h1>{title}</h1> {children} </section> ) } function Button({ show, children }) { if (show) { const theme = use(ThemeContext); const className = 'button-' + theme; return ( <button className={className}> {children} </button> ); } return false }
Diffuser en continu des données du serveur au client
Les données peuvent être transmises en continu du serveur au client en passant une promesse comme prop depuis un Composant Serveur vers un Composant Client.
import { fetchMessage } from './lib.js';
import { Message } from './message.js';
export default function App() {
const messagePromise = fetchMessage();
return (
<Suspense fallback={<p>En attente d’un message...</p>}>
<Message messagePromise={messagePromise} />
</Suspense>
);
}
Le Composant Client prend ensuite la promesse qu’il a reçue comme prop et la transmet à l’API use
. Ça permet au Composant Client de lire la valeur de la promesse initialement créée par le Composant Serveur.
// message.js
'use client';
import { use } from 'react';
export function Message({ messagePromise }) {
const messageContent = use(messagePromise);
return <p>Voici le message : {messageContent}</p>;
}
Puisque Message
est enrobé dans un Suspense
, l’UI de secours sera affichée en attendant l’accomplissement de la promesse. Lorsqu’elle s’accomplit, la valeur sera lue par l’API use
et le composant Message
remplacera l’UI de secours de Suspense.
"use client"; import { use, Suspense } from "react"; function Message({ messagePromise }) { const messageContent = use(messagePromise); return <p>Voici le message : {messageContent}</p>; } export function MessageContainer({ messagePromise }) { return ( <Suspense fallback={<p>⌛ Téléchargement du message...</p>}> <Message messagePromise={messagePromise} /> </Suspense> ); }
En détail
Une promesse peut être passée d’un Composant Serveur à un Composant Client, puis accomplie dans le Composant Client avec l’API use
. Vous pouvez également accomplir la promesse dans un Composant Serveur avec await
, puis transmettre les données requises au Composant Client en tant que prop.
export default async function App() {
const messageContent = await fetchMessage();
return <Message messageContent={messageContent} />
}
Toutefois, l’utilisation d’await
dans un Composant Serveur bloquera son rendu jusqu’à ce que l’instruction await
ait terminé. Le passage d’une promesse d’un Composant Serveur à un Composant Client permet à la promesse de ne pas bloquer le rendu du Composant Serveur.
Traiter les promesses rejetées
Dans certains cas, une promesse passée à use
peut être rejetée. Vous pouvez gérer les promesses rejetées en utilisant l’une ou l’autre de ces méthodes :
- afficher une erreur aux utilisateurs avec un périmètre d’erreur
- fournir une valeur alternative avec
Promise.catch
Afficher une erreur aux utilisateurs avec un périmètre d’erreur
Si vous souhaitez afficher une erreur à vos utilisateurs quand une promesse a été rejetée, vous pouvez utiliser un périmètre d’erreur. Pour l’utiliser, enrobez le composant d’où vous appelez l’API use
dans le périmètre d’erreur. Si la promesse transmise à use
est rejetée, alors l’UI de secours de ce périmètre d’erreur sera affichée.
"use client"; import { use, Suspense } from "react"; import { ErrorBoundary } from "react-error-boundary"; export function MessageContainer({ messagePromise }) { return ( <ErrorBoundary fallback={<p>⚠️ Ça sent le pâté…</p>}> <Suspense fallback={<p>⌛ Téléchargement du message...</p>}> <Message messagePromise={messagePromise} /> </Suspense> </ErrorBoundary> ); } function Message({ messagePromise }) { const content = use(messagePromise); return <p>Voici le message : {content}</p>; }
Fournir une valeur alternative avec Promise.catch
Si vous voulez fournir une valeur alternative quand la promesse passée à use
est rejetée, vous pouvez utiliser la méthode catch
des promesses.
import { Message } from './message.js';
export default function App() {
const messagePromise = new Promise((resolve, reject) => {
reject();
}).catch(() => {
return "Aucun nouveau message.";
});
return (
<Suspense fallback={<p>En attente de message...</p>}>
<Message messagePromise={messagePromise} />
</Suspense>
);
}
Pour utiliser la méthode catch
de la promesse, appelez catch
sur l’objet Promise
. catch
n’accepte qu’un seul paramètre : une fonction qui prend une erreur comme argument. La valeur de retour de la fonction passée à catch
sera utilisée comme valeur accomplie de la promesse.
Dépannage
“Suspense Exception: This is not a real error!”
(« Exception Suspense : ce n’est pas une véritable erreur ! », NdT)
Vous appelez probablement use
soit en-dehors d’un composant React ou d’une fonction de Hook, soit dans un bloc try-catch. Pour corriger ce dernier cas, enrobez votre composant dans un périmètre d’erreur ou appelez la fonction catch
de la promesse pour attraper l’erreur et résoudre la promesse avec une valeur différente. Consultez ces exemples.
Si vous appelez use
en-dehors d’un composant React ou d’une fonction de Hook, déplacez l’appel à use
dans un composant React ou une fonction de Hook.
function MessageComponent({messagePromise}) {
function download() {
// ❌ la fonction appelant `use` n'est ni un composant ni un Hook
const message = use(messagePromise);
// ...
Appelez plutôt use
hors de toute fermeture lexicale au sein du composant, lorsque la fonction qui appelle use
est un composant ou un Hook.
function MessageComponent({messagePromise}) {
// ✅ `use` est appelé depuis un composant
const message = use(messagePromise);
// ...