From 1b81c41c9dfc7bd03cb8d8e9bc46f8d1a36fc1da Mon Sep 17 00:00:00 2001 From: Christophe Porteneuve Date: Sat, 15 Jul 2023 03:58:47 +0200 Subject: [PATCH 1/3] copy(useTransition): translate intro, ref and usage --- src/content/reference/react/Suspense.md | 4 +- src/content/reference/react/useTransition.md | 304 ++++++++++--------- 2 files changed, 160 insertions(+), 148 deletions(-) diff --git a/src/content/reference/react/Suspense.md b/src/content/reference/react/Suspense.md index 085173a4f..d00489745 100644 --- a/src/content/reference/react/Suspense.md +++ b/src/content/reference/react/Suspense.md @@ -2137,7 +2137,7 @@ Une transition n'attend pas que *tout* le contenu soit chargé. Elle attend seul -Les routeurs intégrant Suspense sont censés enrober par défaut leurs navigations dans des transitions. +Les routeurs compatibles Suspense sont censés enrober par défaut leurs navigations dans des transitions. @@ -2534,7 +2534,7 @@ Pendant une transition, React évitera de masquer du contenu déjà révélé. C Imaginez que vous naviguiez au sein d'une page de profil utilisateur, et que quelque chose suspende. Si cette mise à jour est enrobée dans une transition, elle ne déclenchera pas de contenu de secours pour le contenu déjà visible. C'est bien le comportement attendu. -En revanche, imaginez maintenant que vous naviguiez entre deux profils utilisateurs différents. Dans ce cas, afficher le contenu de secours aurait du sens. Par exemple, le fil des publications d'un utilisateur constitue un *contenu différent* de celui d'un autre utilisateur. En spécifiant une `key`, vous garantissez que React traitera les fils de publications d'utilisateurs différents comme des composants différents, et réinitialisera les périmètres Suspense lors de la navigation. Les routeurs intégrant Suspense sont censés le faire automatiquement. +En revanche, imaginez maintenant que vous naviguiez entre deux profils utilisateurs différents. Dans ce cas, afficher le contenu de secours aurait du sens. Par exemple, le fil des publications d'un utilisateur constitue un *contenu différent* de celui d'un autre utilisateur. En spécifiant une `key`, vous garantissez que React traitera les fils de publications d'utilisateurs différents comme des composants différents, et réinitialisera les périmètres Suspense lors de la navigation. Les routeurs compatibles Suspense sont censés le faire automatiquement. --- diff --git a/src/content/reference/react/useTransition.md b/src/content/reference/react/useTransition.md index a6fcde710..186564f7a 100644 --- a/src/content/reference/react/useTransition.md +++ b/src/content/reference/react/useTransition.md @@ -4,7 +4,7 @@ title: useTransition -`useTransition` is a React Hook that lets you update the state without blocking the UI. +`useTransition` est un Hook React qui vous permet de mettre à jour l'état sans bloquer l'UI. ```js const [isPending, startTransition] = useTransition() @@ -16,11 +16,11 @@ const [isPending, startTransition] = useTransition() --- -## Reference {/*reference*/} +## Référence {/*reference*/} ### `useTransition()` {/*usetransition*/} -Call `useTransition` at the top level of your component to mark some state updates as transitions. +Appelez `useTransition` au niveau racine de votre composant pour marquer certaines mises à jour d'état comme étant des transitions. ```js import { useTransition } from 'react'; @@ -31,24 +31,24 @@ function TabContainer() { } ``` -[See more examples below.](#usage) +[Voir d'autres exemples ci-dessous](#usage). -#### Parameters {/*parameters*/} +#### Paramètres {/*parameters*/} -`useTransition` does not take any parameters. +`useTransition` ne prend aucun argument. -#### Returns {/*returns*/} +#### Valeur renvoyée {/*returns*/} -`useTransition` returns an array with exactly two items: +`useTransition` renvoie un tableau avec exactement deux éléments : -1. The `isPending` flag that tells you whether there is a pending transition. -2. The [`startTransition` function](#starttransition) that lets you mark a state update as a transition. +1. Le drapeau `isPending` qui vous indique si la transition est en cours. +2. La [fonction `startTransition`](#starttransition) qui vous permet de marquer une mise à jour d'état comme étant une transition. --- -### `startTransition` function {/*starttransition*/} +### La fonction `startTransition` {/*starttransition*/} -The `startTransition` function returned by `useTransition` lets you mark a state update as a transition. +La fonction `startTransition` renvoyée par `useTransition` vous permet de marquer une mise à jour d'état comme étant une transition. ```js {6,8} function TabContainer() { @@ -64,35 +64,35 @@ function TabContainer() { } ``` -#### Parameters {/*starttransition-parameters*/} +#### Paramètres {/*starttransition-parameters*/} -* `scope`: A function that updates some state by calling one or more [`set` functions.](/reference/react/useState#setstate) React immediately calls `scope` with no parameters and marks all state updates scheduled synchronously during the `scope` function call as transitions. They will be [non-blocking](#marking-a-state-update-as-a-non-blocking-transition) and [will not display unwanted loading indicators.](#preventing-unwanted-loading-indicators) +* `scope` : une fonction qui met à jour l'état en appelant au moins une [fonction `set`](/reference/react/useState#setstate). React appelle immédiatement `scope` sans argument et marque toutes les mises à jour d'état demandées durant l'exécution synchrone de `scope` comme des transitions. Elles seront [non bloquantes](/reference/react/useTransition#marking-a-state-update-as-a-non-blocking-transition) et [n'afficheront pas d'indicateurs de chargement indésirables](/reference/react/useTransition#preventing-unwanted-loading-indicators). -#### Returns {/*starttransition-returns*/} +#### Valeur renvoyée {/*starttransition-returns*/} -`startTransition` does not return anything. +`startTransition` ne renvoie rien. -#### Caveats {/*starttransition-caveats*/} +#### Limitations {/*starttransition-caveats*/} -* `useTransition` is a Hook, so it can only be called inside components or custom Hooks. If you need to start a transition somewhere else (for example, from a data library), call the standalone [`startTransition`](/reference/react/startTransition) instead. +* `useTransition` est un Hook, il ne peut donc être appelé qu'au sein de composants ou de Hooks personnalisés. Si vous avez besoin de démarrer une transition à un autre endroit (par exemple, depuis une bibliothèque de gestion de données), utilisez plutôt la fonction autonome [`startTransition`](/reference/react/startTransition). -* You can wrap an update into a transition only if you have access to the `set` function of that state. If you want to start a transition in response to some prop or a custom Hook value, try [`useDeferredValue`](/reference/react/useDeferredValue) instead. +* Vous pouvez enrober une mise à jour dans une transition uniquement si vous avez accès à la fonction `set` de l'état en question. Si vous souhaitez démarrer une transition en réaction à une prop ou à la valeur renvoyée par un Hook personnalisé, utilisez plutôt [`useDeferredValue`](/reference/react/useDeferredValue). -* The function you pass to `startTransition` must be synchronous. React immediately executes this function, marking all state updates that happen while it executes as transitions. If you try to perform more state updates later (for example, in a timeout), they won't be marked as transitions. +* La fonction que vous passez à `startTransition` doit être synchrone. React exécute cette fonction immédiatement, et marque toutes les mises à jour demandées lors de son exécution comme des transitions. Si vous essayez de faire des mises à jour d'état plus tard (par exemple avec un timer), elles ne seront pas marquées comme des transitions. -* A state update marked as a transition will be interrupted by other state updates. For example, if you update a chart component inside a transition, but then start typing into an input while the chart is in the middle of a re-render, React will restart the rendering work on the chart component after handling the input update. +* Une mise à jour d'état marquée comme une transition pourra être interrompue par d'autres mises à jour d'état. Par exemple, si vous mettez à jour un composant de graphe au sein d'une transition, mais commencez alors une saisie dans un champ texte tandis que le graphe est en train de refaire son rendu, React redémarrera le rendu du composant graphe après avoir traité la mise à jour d'état du champ. -* Transition updates can't be used to control text inputs. +* Les mises à jour en transition ne peuvent pas être utilisées pour contrôler des champs textuels. -* If there are multiple ongoing transitions, React currently batches them together. This is a limitation that will likely be removed in a future release. +* Si plusieurs transitions sont en cours, React les regroupe pour le moment. Cette limitation sera sans doute levée dans une future version. --- -## Usage {/*usage*/} +## Utilisation {/*usage*/} -### Marking a state update as a non-blocking transition {/*marking-a-state-update-as-a-non-blocking-transition*/} +### Marquer une mise à jour d'état comme étant une transition non bloquante {/*marking-a-state-update-as-a-non-blocking-transition*/} -Call `useTransition` at the top level of your component to mark state updates as non-blocking *transitions*. +Appelez `useTransition` au niveau racine de votre composant pour marquer des mises à jour d'état comme étant des *transitions* non bloquantes. ```js [[1, 4, "isPending"], [2, 4, "startTransition"]] import { useState, useTransition } from 'react'; @@ -103,12 +103,12 @@ function TabContainer() { } ``` -`useTransition` returns an array with exactly two items: +`useTransition` renvoie un tableau avec exactement deux éléments : -1. The `isPending` flag that tells you whether there is a pending transition. -2. The `startTransition` function that lets you mark a state update as a transition. +1. Le drapeau `isPending` qui vous indique si la transition est en cours. +2. La fonction `startTransition` qui vous permet de marquer une mise à jour d'état comme étant une transition. -You can then mark a state update as a transition like this: +Vous pouvez marquer une mise à jour d'état comme étant une transition comme ceci : ```js {6,8} function TabContainer() { @@ -124,17 +124,17 @@ function TabContainer() { } ``` -Transitions let you keep the user interface updates responsive even on slow devices. +Les transitions vous permettent de conserver des mises à jour d'interface utilisateur réactives même sur des appareils lents. -With a transition, your UI stays responsive in the middle of a re-render. For example, if the user clicks a tab but then change their mind and click another tab, they can do that without waiting for the first re-render to finish. +Avec une transition, votre UI reste réactive pendant le rendu. Par exemple, si l'utilisateur clique sur un onglet mais ensuite change d'avis et va sur un autre onglet, il peut le faire sans devoir d'abord attendre que le premier onglet ait fini son rendu. - + -#### Updating the current tab in a transition {/*updating-the-current-tab-in-a-transition*/} +#### Changer l'onglet actif au sein d'une transition {/*updating-the-current-tab-in-a-transition*/} -In this example, the "Posts" tab is **artificially slowed down** so that it takes at least a second to render. +Dans cet exemple, l'onglet « Articles » est **artificiellement ralenti** pour que son rendu prenne au moins une seconde. -Click "Posts" and then immediately click "Contact". Notice that this interrupts the slow render of "Posts". The "Contact" tab shows immediately. Because this state update is marked as a transition, a slow re-render did not freeze the user interface. +Cliquez sur « Articles » puis cliquez immédiatement sur « Contact ». Remarquez que ça interrompt le rendu lent d'« Articles ». L'onglet « Contact » est affiché immédiatement. Puisque la mise à jour d'état est marquée comme une transition, un rendu lent ne gèle pas pour autant l'interface utilisateur. @@ -151,7 +151,7 @@ export default function TabContainer() { function selectTab(nextTab) { startTransition(() => { - setTab(nextTab); + setTab(nextTab); }); } @@ -161,13 +161,13 @@ export default function TabContainer() { isActive={tab === 'about'} onClick={() => selectTab('about')} > - About + À propos selectTab('posts')} > - Posts (slow) + Articles (lent) Welcome to my profile!

+

Bienvenue sur mon profil !

); } ``` @@ -214,8 +214,8 @@ export default function AboutTab() { import { memo } from 'react'; const PostsTab = memo(function PostsTab() { - // Log once. The actual slowdown is inside SlowPost. - console.log('[ARTIFICIALLY SLOW] Rendering 500 '); + // Un seul log. La lenteur réside en fait dans SlowPost. + console.log('[ARTIFICIELLEMENT LENT] Rendu de 500 '); let items = []; for (let i = 0; i < 500; i++) { @@ -231,12 +231,13 @@ const PostsTab = memo(function PostsTab() { function SlowPost({ index }) { let startTime = performance.now(); while (performance.now() - startTime < 1) { - // Do nothing for 1 ms per item to emulate extremely slow code + // Ne rien faire pendant 1 ms par élément pour simuler + // du code extrêmement lent. } return (
  • - Post #{index + 1} + Article #{index + 1}
  • ); } @@ -249,7 +250,7 @@ export default function ContactTab() { return ( <>

    - You can find me online here: + Vous me trouverez en ligne ici :

    • admin@mysite.com
    • @@ -269,11 +270,11 @@ b { display: inline-block; margin-right: 10px; } -#### Updating the current tab without a transition {/*updating-the-current-tab-without-a-transition*/} +#### Changer l'onglet actif sans transitions {/*updating-the-current-tab-without-a-transition*/} -In this example, the "Posts" tab is also **artificially slowed down** so that it takes at least a second to render. Unlike in the previous example, this state update is **not a transition.** +Dans cet exemple, l'onglet « Articles » est toujours **artificiellement ralenti** pour que son rendu prenne au moins une seconde. Mais contrairement à l'exemple précédent, la mise à jour d'état ne figure **pas dans une transition**. -Click "Posts" and then immediately click "Contact". Notice that the app freezes while rendering the slowed down tab, and the UI becomes unresponsive. This state update is not a transition, so a slow re-render freezed the user interface. +Cliquez sur « Articles » puis cliquez immédiatement sur « Contact ». Remarquez que l'appli gèle pendant le rendu de l'onglet lent, et que l'UI ne répond plus. La mise à jour d'état ne figure pas dans une transition, de sorte que le rendu lent gèle l'interface utilisateur. @@ -297,13 +298,13 @@ export default function TabContainer() { isActive={tab === 'about'} onClick={() => selectTab('about')} > - About + À propos selectTab('posts')} > - Posts (slow) + Articles (lent) Welcome to my profile!

      +

      Bienvenue sur mon profil !

      ); } ``` @@ -350,8 +351,8 @@ export default function AboutTab() { import { memo } from 'react'; const PostsTab = memo(function PostsTab() { - // Log once. The actual slowdown is inside SlowPost. - console.log('[ARTIFICIALLY SLOW] Rendering 500 '); + // Un seul log. La lenteur réside en fait dans SlowPost. + console.log('[ARTIFICIELLEMENT LENT] Rendu de 500 '); let items = []; for (let i = 0; i < 500; i++) { @@ -367,12 +368,13 @@ const PostsTab = memo(function PostsTab() { function SlowPost({ index }) { let startTime = performance.now(); while (performance.now() - startTime < 1) { - // Do nothing for 1 ms per item to emulate extremely slow code + // Ne rien faire pendant 1 ms par élément pour simuler + // du code extrêmement lent. } return (
    • - Post #{index + 1} + Article #{index + 1}
    • ); } @@ -385,7 +387,7 @@ export default function ContactTab() { return ( <>

      - You can find me online here: + Vous me trouverez en ligne ici :

      • admin@mysite.com
      • @@ -409,9 +411,9 @@ b { display: inline-block; margin-right: 10px; } --- -### Updating the parent component in a transition {/*updating-the-parent-component-in-a-transition*/} +### Mettre à jour le composant parent dans une transition {/*updating-the-parent-component-in-a-transition*/} -You can update a parent component's state from the `useTransition` call, too. For example, this `TabButton` component wraps its `onClick` logic in a transition: +Vous pouvez tout aussi bien mettre à jour l'état du composant parent depuis un appel à `useTransition`. Par exemple, le composant `TabButton` enrobe a logique de son `onClick` avec une transition : ```js {8-10} export default function TabButton({ children, isActive, onClick }) { @@ -431,7 +433,7 @@ export default function TabButton({ children, isActive, onClick }) { } ``` -Because the parent component updates its state inside the `onClick` event handler, that state update gets marked as a transition. This is why, like in the earlier example, you can click on "Posts" and then immediately click "Contact". Updating the selected tab is marked as a transition, so it does not block user interactions. +Puisque le composant parent met à jour son état au sein du gestionnaire d'événement `onClick`, cette mise à jour d'état sera marquée comme étant une transition. C'est pourquoi, comme dans l'exemple précédent, vous pouvez cliquer sur « Articles » puis immédiatement sur « Contact ». Le changement d'onglet est marqué comme une transition : il ne bloque donc pas les interactions utilisateur. @@ -450,13 +452,13 @@ export default function TabContainer() { isActive={tab === 'about'} onClick={() => setTab('about')} > - About + À propos setTab('posts')} > - Posts (slow) + Articles (lent) Welcome to my profile!

        +

        Bienvenue sur mon profil !

        ); } ``` @@ -505,8 +507,8 @@ export default function AboutTab() { import { memo } from 'react'; const PostsTab = memo(function PostsTab() { - // Log once. The actual slowdown is inside SlowPost. - console.log('[ARTIFICIALLY SLOW] Rendering 500 '); + // Un seul log. La lenteur réside en fait dans SlowPost. + console.log('[ARTIFICIELLEMENT LENT] Rendu de 500 '); let items = []; for (let i = 0; i < 500; i++) { @@ -522,12 +524,13 @@ const PostsTab = memo(function PostsTab() { function SlowPost({ index }) { let startTime = performance.now(); while (performance.now() - startTime < 1) { - // Do nothing for 1 ms per item to emulate extremely slow code + // Ne rien faire pendant 1 ms par élément pour simuler + // du code extrêmement lent. } return (
      • - Post #{index + 1} + Article #{index + 1}
      • ); } @@ -540,7 +543,7 @@ export default function ContactTab() { return ( <>

        - You can find me online here: + Vous me trouverez en ligne ici :

        • admin@mysite.com
        • @@ -560,9 +563,9 @@ b { display: inline-block; margin-right: 10px; } --- -### Displaying a pending visual state during the transition {/*displaying-a-pending-visual-state-during-the-transition*/} +### Afficher une indication visuelle pendant la transition {/*displaying-a-pending-visual-state-during-the-transition*/}ç {/*afficher-une-indication-visuelle-pendant-la-transition-displaying-a-pending-visual-state-during-the-transitionç*/} -You can use the `isPending` boolean value returned by `useTransition` to indicate to the user that a transition is in progress. For example, the tab button can have a special "pending" visual state: +Vous pouvez utiliser la valeur booléenne `isPending` renvoyée par `useTransition` pour indiquer à l'utilisateur qu'une transition est en cours. Par exemple, le bouton d'onglet peut avoir un état visuel spécial « en cours » : ```js {4-6} function TabButton({ children, isActive, onClick }) { @@ -574,7 +577,7 @@ function TabButton({ children, isActive, onClick }) { // ... ``` -Notice how clicking "Posts" now feels more responsive because the tab button itself updates right away: +Remarquez que le clic sur « Articles » semble désormais plus réactif parce que le bouton d'onglet lui-même se met à jour immédiatement : @@ -593,13 +596,13 @@ export default function TabContainer() { isActive={tab === 'about'} onClick={() => setTab('about')} > - About + À propos setTab('posts')} > - Posts (slow) + Articles (lent) Welcome to my profile!

          +

          Bienvenue sur mon profil !

          ); } ``` @@ -651,8 +654,8 @@ export default function AboutTab() { import { memo } from 'react'; const PostsTab = memo(function PostsTab() { - // Log once. The actual slowdown is inside SlowPost. - console.log('[ARTIFICIALLY SLOW] Rendering 500 '); + // Un seul log. La lenteur réside en fait dans SlowPost. + console.log('[ARTIFICIELLEMENT LENT] Rendu de 500 '); let items = []; for (let i = 0; i < 500; i++) { @@ -668,12 +671,13 @@ const PostsTab = memo(function PostsTab() { function SlowPost({ index }) { let startTime = performance.now(); while (performance.now() - startTime < 1) { - // Do nothing for 1 ms per item to emulate extremely slow code + // Ne rien faire pendant 1 ms par élément pour simuler + // du code extrêmement lent. } return (
        • - Post #{index + 1} + Article #{index + 1}
        • ); } @@ -686,7 +690,7 @@ export default function ContactTab() { return ( <>

          - You can find me online here: + Vous me trouverez en ligne ici :

          • admin@mysite.com
          • @@ -707,9 +711,9 @@ b { display: inline-block; margin-right: 10px; } --- -### Preventing unwanted loading indicators {/*preventing-unwanted-loading-indicators*/} +### Empêcher les indicateurs de chargement indésirables {/*preventing-unwanted-loading-indicators*/} -In this example, the `PostsTab` component fetches some data using a [Suspense-enabled](/reference/react/Suspense) data source. When you click the "Posts" tab, the `PostsTab` component *suspends*, causing the closest loading fallback to appear: +Dans cet exemple, le composant `PostsTab` charge des données en utilisant une source de données [compatible Suspense](/reference/react/Suspense). Lorsque vous cliquez sur l'onglet « Articles », le composant `PostsTab` *suspend*, entraînant l'affichage du plus proche contenu de secours : @@ -723,18 +727,18 @@ import ContactTab from './ContactTab.js'; export default function TabContainer() { const [tab, setTab] = useState('about'); return ( - 🌀 Loading...}> + 🌀 Chargement...}> setTab('about')} > - About + À propos setTab('posts')} > - Posts + Articles