From 6ead702e741b2554f761c8b1dc6e0d13b2b93229 Mon Sep 17 00:00:00 2001 From: nalin8 Date: Wed, 31 May 2023 00:48:28 +0200 Subject: [PATCH 1/6] Translation of the 'useDeferredValue' page --- .../reference/react/useDeferredValue.md | 221 +++++++++--------- 1 file changed, 110 insertions(+), 111 deletions(-) diff --git a/src/content/reference/react/useDeferredValue.md b/src/content/reference/react/useDeferredValue.md index 3f2a8a5d9..6289790c6 100644 --- a/src/content/reference/react/useDeferredValue.md +++ b/src/content/reference/react/useDeferredValue.md @@ -4,7 +4,7 @@ title: useDeferredValue -`useDeferredValue` is a React Hook that lets you defer updating a part of the UI. +`useDeferredValue` est un Hook React qui vous laisse délayer (*defer, NdT*) une partie de l'UI. ```js const deferredValue = useDeferredValue(value) @@ -16,11 +16,11 @@ const deferredValue = useDeferredValue(value) --- -## Reference {/*reference*/} +## Référence {/*reference*/} ### `useDeferredValue(value)` {/*usedeferredvalue*/} -Call `useDeferredValue` at the top level of your component to get a deferred version of that value. +Appelez `useDeferredValue` à la racine de votre composant pour recevoir une version délayée de cette valeur. ```js import { useState, useDeferredValue } from 'react'; @@ -32,37 +32,37 @@ function SearchPage() { } ``` -[See more examples below.](#usage) +[Voir d’autres exemples ci-dessous.](#usage) -#### Parameters {/*parameters*/} +#### Paramètres {/*parameters*/} -* `value`: The value you want to defer. It can have any type. +* `value`: La valeur que vous souhaitez délayer. Elle peut avoir n'importe quel type. -#### Returns {/*returns*/} +#### Valeur renvoyée {/*returns*/} -During the initial render, the returned deferred value will be the same as the value you provided. During updates, React will first attempt a re-render with the old value (so it will return the old value), and then try another re-render in background with the new value (so it will return the updated value). +Durant le rendu initial, la valeur délayée retournée sera semblable à la valeur que vous avez donné en entrée. Pendant les mises à jour, React va d'abord tenter un re-render avec l'ancienne valeur (il va donc retourner l'ancienne valeur), et ensuite essayer un autre re-render en arrière-plan avec la nouvelle valeur (il va donc retourner la valeur mise à jour). -#### Caveats {/*caveats*/} +#### Limitations {/*caveats*/} -- The values you pass to `useDeferredValue` should either be primitive values (like strings and numbers) or objects created outside of rendering. If you create a new object during rendering and immediately pass it to `useDeferredValue`, it will be different on every render, causing unnecessary background re-renders. +- Les valeurs que vous passez à `useDeferredValue` doivent soit être des valeurs primitives (comme des chaînes de caractères ou des nombres), soit des objets créés en-dehors du rendu. Si vous créez un nouvel objet pendant le rendu et que vous le passez immédiatement à `useDeferredValue`, il sera différent à chaque rendu, causant des re-renders inutiles en arrière-plan. -- When `useDeferredValue` receives a different value (compared with [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is)), in addition to the current render (when it still uses the previous value), it schedules a re-render in the background with the new value. The background re-render is interruptible: if there's another update to the `value`, React will restart the background re-render from scratch. For example, if the user is typing into an input faster than a chart receiving its deferred value can re-render, the chart will only re-render after the user stops typing. +- Quand `useDeferredValue` reçoit une valeur différente (comparaison logique avec [`Object.is`](https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Global_Objects/Object/is)), en plus du rendu en cours (quand il utilise toujours la valeur précédente), il planifie un re-render en arrière-plan avec la nouvelle valeur. Le re-render en arrière-plan est susceptible d'être interrompu (*interruptible, NdT*) : s'il y a un nouvelle mise à jour de `value`, React va redémarrer le re-render depuis le début. Par exemple, si l'utilisateur écrit dans une entrée plus rapidement que la vitesse à laquelle un graphique peut re-render sa valeur délayée, le graphique ne se mettra à jour seulement après que l'utilisateur ait arrêté d'écrire. -- `useDeferredValue` is integrated with [``.](/reference/react/Suspense) If the background update caused by a new value suspends the UI, the user will not see the fallback. They will see the old deferred value until the data loads. +- `useDeferredValue` est intégré avec [``.](/reference/react/Suspense) Si l'UI est suspendue à cause d'un mise à jour de l'arrière-plan causée par une nouvelle valeur, l'utilisateur ne verra pas le fallback (*recours prévu en cas de suspension de l'UI, NdT*). Il verra l'ancienne valeur délayée jusqu'à ce que les données chargent. -- `useDeferredValue` does not by itself prevent extra network requests. +- `useDeferredValue` n'empêche pas par lui-même des requêtes réseau supplémentaires. -- There is no fixed delay caused by `useDeferredValue` itself. As soon as React finishes the original re-render, React will immediately start working on the background re-render with the new deferred value. Any updates caused by events (like typing) will interrupt the background re-render and get prioritized over it. +- Il n'y a pas de délai fixé causé par `useDeferredValue` en lui-même. Dès que React finit son re-render originel, React va immédiatement commencer à travailler sur le re-render de l'arrière-plan avec la nouvelle valeur délayée. Toute mise à jour causée par des évènements (comme écrire dans un champ de saisie) va interrompre le re-render en arrière-plan et sera priorisée par rapport à celui-ci. -- The background re-render caused by `useDeferredValue` does not fire Effects until it's committed to the screen. If the background re-render suspends, its Effects will run after the data loads and the UI updates. +- Le rendu causé par un `useDeferredValue` ne déclenche pas des Effets, jusqu'à ce qu'il soit envoyé sur l'écran. Si le re-render de l'arrière-plan se suspend, ses Effets vont se lancer après que les données soit chargées et que l'UI soit mise à jour. --- -## Usage {/*usage*/} +## Utilisation {/*usage*/} -### Showing stale content while fresh content is loading {/*showing-stale-content-while-fresh-content-is-loading*/} +### Affichage du contenu obsolète pendant le chargement du nouveau contenu {/*showing-stale-content-while-fresh-content-is-loading*/} -Call `useDeferredValue` at the top level of your component to defer updating some part of your UI. +Appellez `useDeferredValue` à la racine de votre composant pour délayer la mise à jour de certaines parties de votre UI. ```js [[1, 5, "query"], [2, 5, "deferredQuery"]] import { useState, useDeferredValue } from 'react'; @@ -74,25 +74,25 @@ function SearchPage() { } ``` -During the initial render, the deferred value will be the same as the value you provided. +Durant le rendu initial, la valeur délayée sera la même que la valeur que vous avez donné. -During updates, the deferred value will "lag behind" the latest value. In particular, React will first re-render *without* updating the deferred value, and then try to re-render with the newly received value in background. +Pendant la mise à jour, la valeur délayée va "être en retard" par rapport à la dernière valeur. Plus particulièrement, React va d'abord faire un rendu *sans* mettre à jour la valeur délayée, et puis essayer un autre rendu avec la nouvelle valeur reçue en arrière-plan. -**Let's walk through an example to see when this is useful.** +**Essayons un exemple afin de comprendre l'utilité de ce Hook.** -This example assumes you use one of Suspense-enabled data sources: +Cet exemple part du principe que vous utilisez une de ces méthodes intégrées avec Suspense : -- Data fetching with Suspense-enabled frameworks like [Relay](https://relay.dev/docs/guided-tour/rendering/loading-states/) and [Next.js](https://nextjs.org/docs/advanced-features/react-18) -- Lazy-loading component code with [`lazy`](/reference/react/lazy) +- Des frameworks de récupération de données utilisant Suspense comme [Relay](https://relay.dev/docs/guided-tour/rendering/loading-states/) ou [Next.js](https://nextjs.org/docs/advanced-features/react-18) +- Des composants de Lazy-loading (*chargement fainéant, NdT*) avec [`lazy`](/reference/react/lazy) -[Learn more about Suspense and its limitations.](/reference/react/Suspense) +[Apprenez-en plus à propos de Suspense et de ses limitations.](/reference/react/Suspense) -In this example, the `SearchResults` component [suspends](/reference/react/Suspense#displaying-a-fallback-while-content-is-loading) while fetching the search results. Try typing `"a"`, waiting for the results, and then editing it to `"ab"`. The results for `"a"` get replaced by the loading fallback. +Dans cet exemple, le composant `SearchResults` va se [suspendre](/reference/react/Suspense#displaying-a-fallback-while-content-is-loading) en récupérant les résultats de recherche. Essayez en écrivant `"a"`, attendez que les résultats s'affichent, puis éditez en écrivant `"ab"`. Les résultats de `"a"` sont remplacés par un chargement. @@ -120,10 +120,10 @@ export default function App() { return ( <> - Loading...}> + Chargement...}> @@ -134,11 +134,11 @@ export default function App() { ```js SearchResults.js hidden import { fetchData } from './data.js'; -// Note: this component is written using an experimental API -// that's not yet available in stable versions of React. +// Note: ce composant est écrit en utilisant une API expérimentale +// qui n'est pas encore disponible dans les versions stables de React. -// For a realistic example you can follow today, try a framework -// that's integrated with Suspense, like Relay or Next.js. +// Pour un exemple réaliste que vous pouvez suivre aujourd'hui, +// essayez un framework intégré avec Suspense, comme Relay ou Next.js. export default function SearchResults({ query }) { if (query === '') { @@ -146,7 +146,7 @@ export default function SearchResults({ query }) { } const albums = use(fetchData(`/search?q=${query}`)); if (albums.length === 0) { - return

No matches for "{query}"

; + return

Pas de résultats pour "{query}"

; } return (
    @@ -159,8 +159,8 @@ export default function SearchResults({ query }) { ); } -// This is a workaround for a bug to get the demo running. -// TODO: replace with real implementation when the bug is fixed. +// C'est une solution de contournement d'un bug pour lancer la démo. +// TODO: replacer avec la vraie implémentation quand le bug sera fixé. function use(promise) { if (promise.status === 'fulfilled') { return promise.value; @@ -186,9 +186,9 @@ function use(promise) { ``` ```js data.js hidden -// Note: the way you would do data fetching depends on -// the framework that you use together with Suspense. -// Normally, the caching logic would be inside a framework. +// Note: la manière dont vous pourriez récupérer les données +// dépends du framework avec lequel vous utilisez Suspense. +// Normalement, la logique de cache serait à l'intérieur d'un framework. let cache = new Map(); @@ -203,12 +203,12 @@ async function getData(url) { if (url.startsWith('/search?q=')) { return await getSearchResults(url.slice('/search?q='.length)); } else { - throw Error('Not implemented'); + throw Error('Non implémenté'); } } async function getSearchResults(query) { - // Add a fake delay to make waiting noticeable. + // Ajoute un faux délai pour que le temps d'attente soit remarqué par l'utilisateur. await new Promise(resolve => { setTimeout(resolve, 500); }); @@ -284,7 +284,7 @@ input { margin: 10px; } -A common alternative UI pattern is to *defer* updating the list of results and to keep showing the previous results until the new results are ready. Call `useDeferredValue` to pass a deferred version of the query down: +Alternativement, une architecture UI couramment utilisée est de *délayer* la mise à jour d'une liste de résultats, et de continuer à montrer les anciens résultats jusqu'à ce que les nouveaux résultats soient prêts. Appellez `useDeferredValue` pour passer en entrée une version reportée de la recherche : ```js {3,11} export default function App() { @@ -293,10 +293,10 @@ export default function App() { return ( <> - Loading...}> + Chargement...}> @@ -304,9 +304,9 @@ export default function App() { } ``` -The `query` will update immediately, so the input will display the new value. However, the `deferredQuery` will keep its previous value until the data has loaded, so `SearchResults` will show the stale results for a bit. +La `query` va se mettre à jour immédiatement, et le champ de saisie va afficher la nouvelle valeur. Cependant, la `deferredQuery` va garder son ancienne valeur jusqu'à ce que les données soient chargées, et `SearchResults` affichera les anciens résultats un court instant. -Enter `"a"` in the example below, wait for the results to load, and then edit the input to `"ab"`. Notice how instead of the Suspense fallback, you now see the stale result list until the new results have loaded: +Entrez `"a"` dans l'exemple ci-dessous, attendez que les résultats soient chargés, et éditez ensuite le champ de saisie pour `"ab"`. Vous pouvez remarquez que, au lieu d'apercevoir le chargement, vous verrez la liste des anciens résultats jusqu'à ce que les nouveaux résultats soient chargés : @@ -335,10 +335,10 @@ export default function App() { return ( <> - Loading...}> + Chargement...}> @@ -349,11 +349,11 @@ export default function App() { ```js SearchResults.js hidden import { fetchData } from './data.js'; -// Note: this component is written using an experimental API -// that's not yet available in stable versions of React. +// Note: ce composant est écrit en utilisant une API expérimentale +// qui n'est pas encore disponible dans les versions stables de React. -// For a realistic example you can follow today, try a framework -// that's integrated with Suspense, like Relay or Next.js. +// Pour un exemple réaliste que vous pouvez suivre aujourd'hui, +// essayez un framework intégré avec Suspense, comme Relay ou Next.js. export default function SearchResults({ query }) { if (query === '') { @@ -361,7 +361,7 @@ export default function SearchResults({ query }) { } const albums = use(fetchData(`/search?q=${query}`)); if (albums.length === 0) { - return

    No matches for "{query}"

    ; + return

    Pas de résultats pour "{query}"

    ; } return (
      @@ -374,8 +374,8 @@ export default function SearchResults({ query }) { ); } -// This is a workaround for a bug to get the demo running. -// TODO: replace with real implementation when the bug is fixed. +// C'est une solution de contournement d'un bug pour lancer la démo. +// TODO: replacer avec la vraie implémentation quand le bug sera fixé. function use(promise) { if (promise.status === 'fulfilled') { return promise.value; @@ -401,9 +401,9 @@ function use(promise) { ``` ```js data.js hidden -// Note: the way you would do data fetching depends on -// the framework that you use together with Suspense. -// Normally, the caching logic would be inside a framework. +// Note: la manière dont vous pourriez récupérer les données +// dépends du framework avec lequel vous utilisez Suspense. +// Normalement, la logique de cache serait à l'intérieur d'un framework. let cache = new Map(); @@ -418,12 +418,12 @@ async function getData(url) { if (url.startsWith('/search?q=')) { return await getSearchResults(url.slice('/search?q='.length)); } else { - throw Error('Not implemented'); + throw Error('Non implémenté'); } } async function getSearchResults(query) { - // Add a fake delay to make waiting noticeable. + // Ajoute un faux délai pour que le temps d'attente soit remarqué par l'utilisateur. await new Promise(resolve => { setTimeout(resolve, 500); }); @@ -501,25 +501,25 @@ input { margin: 10px; } -#### How does deferring a value work under the hood? {/*how-does-deferring-a-value-work-under-the-hood*/} +#### Comment délayer une valeur fonctionne-t-il en sous-jacent ? {/*how-does-deferring-a-value-work-under-the-hood*/} -You can think of it as happening in two steps: +Vous pouvez imaginer le déroulement en deux étapes : -1. **First, React re-renders with the new `query` (`"ab"`) but with the old `deferredQuery` (still `"a")`.** The `deferredQuery` value, which you pass to the result list, is *deferred:* it "lags behind" the `query` value. +1. **Premièrement, React re-renders avec la nouvelle `query` (`"ab"`) mais avec l'ancienne `deferredQuery` (toujours `"a")`.** La valeur `deferredQuery`, à laquelle vous passez la liste de résultats, est *délayée:* elle "se met en retard" par rapport à la valeur `query`. -2. **In background, React tries to re-render with *both* `query` and `deferredQuery` updated to `"ab"`.** If this re-render completes, React will show it on the screen. However, if it suspends (the results for `"ab"` have not loaded yet), React will abandon this rendering attempt, and retry this re-render again after the data has loaded. The user will keep seeing the stale deferred value until the data is ready. +2. **En arrière-plan, React essaye de re-render avec `query` et `deferredQuery` mis à jour *ensemble* avec `"ab"`.** Si ce re-render réussi, React vous le montre sur l'écran. Cependant, s'il se suspend (les résultats pour `"ab"` n'ont pas encore été chargés), React va abandonner cet essai de rendu, et essayer de re-render après que les données aient été chargées. L'utilisateur va continuer à voir l'ancienne valeur reportée jusqu'à ce que les données soient chargées. -The deferred "background" rendering is interruptible. For example, if you type into the input again, React will abandon it and restart with the new value. React will always use the latest provided value. +Le rendu de "l'arrière-plan" délayé est susceptible d'être interrompu. Par exemple, si vous tapez dans la zone de saisie à nouveau, React va l'abandonner et recommencer avec la nouvelle valeur. React va toujours utiliser la dernière valeur donnée. -Note that there is still a network request per each keystroke. What's being deferred here is displaying results (until they're ready), not the network requests themselves. Even if the user continues typing, responses for each keystroke get cached, so pressing Backspace is instant and doesn't fetch again. +Notez qu'il y a toujours une requête réseau par frappe au clavier. Ce qui est reporté ici est l'affichage des résultats (jusqu'à ce qu'ils soient prêts), et non pas les requêtes réseaux en elle-mêmes. Même si l'utilisateur continue à écrire, les réponses pour chaque frappe au clavier sont cachées (*cached, NdT*), et donc les données ne sont pas récupérées une fois de plus lorsqu'on appuie sur Espace. Cette frappe est par ailleurs instantanée. --- -### Indicating that the content is stale {/*indicating-that-the-content-is-stale*/} +### Indiquer que le contenu est obsolète {/*indicating-that-the-content-is-stale*/} -In the example above, there is no indication that the result list for the latest query is still loading. This can be confusing to the user if the new results take a while to load. To make it more obvious to the user that the result list does not match the latest query, you can add a visual indication when the stale result list is displayed: +Dans l'exemple ci-dessous, il n'y aucune indication montrant que la liste des résultats est toujours en train de charger, et qu'elle prend en compte la dernière recherche. Cela peut être dérangeant pour l'utilisateur si les nouveaux résultats prennent du temps à charger. Afin que l'utilisateur comprenne que la liste de résultats n'est pas la même que celle obtenue lors de la dernière recherche, vous pouvez ajouter une indication visuelle lorsque l'ancienne liste de résultats est affichée : ```js {2}
      ``` -With this change, as soon as you start typing, the stale result list gets slightly dimmed until the new result list loads. You can also add a CSS transition to delay dimming so that it feels gradual, like in the example below: +Avec ce changement, dès que vous commencerez à taper, l'ancienne liste de résultats sera légèrement transparente, jusqu'à ce que la nouvelle liste de résultats soit chargée. Vous pouvez également ajouter une transition CSS pour que le rendu soit graduel, comme dans l'exemple ci-dessous : @@ -559,10 +559,10 @@ export default function App() { return ( <> - Loading...}> + Chargement...}>