diff --git a/content/docs/hooks-reference.md b/content/docs/hooks-reference.md index deeef54cf..b6dcaa840 100644 --- a/content/docs/hooks-reference.md +++ b/content/docs/hooks-reference.md @@ -1,22 +1,22 @@ --- id: hooks-reference -title: Hooks API Reference +title: Référence de l'API des Hooks permalink: docs/hooks-reference.html prev: hooks-custom.html next: hooks-faq.html --- -*Hooks* are a new addition in React 16.8. They let you use state and other React features without writing a class. +Les *Hooks* sont une nouveauté de React 16.8. Ils permettent de bénéficier d’un état local et d'autres fonctionnalités de React sans avoir à écrire de classes. -This page describes the APIs for the built-in Hooks in React. +Cette page décrit l’API des Hooks prédéfinis de React. -If you're new to Hooks, you might want to check out [the overview](/docs/hooks-overview.html) first. You may also find useful information in the [frequently asked questions](/docs/hooks-faq.html) section. +Si les Hooks sont nouveaux pour vous, vous voudrez peut-être consulter [l’aperçu](/docs/hooks-overview.html) en premier. Vous trouverez peut-être aussi des informations utiles dans [la foire aux questions](/docs/hooks-faq.html). -- [Basic Hooks](#basic-hooks) +- [Les Hooks de base](#basic-hooks) - [`useState`](#usestate) - [`useEffect`](#useeffect) - [`useContext`](#usecontext) -- [Additional Hooks](#additional-hooks) +- [Hooks supplémentaires](#additional-hooks) - [`useReducer`](#usereducer) - [`useCallback`](#usecallback) - [`useMemo`](#usememo) @@ -25,7 +25,7 @@ If you're new to Hooks, you might want to check out [the overview](/docs/hooks-o - [`useLayoutEffect`](#uselayouteffect) - [`useDebugValue`](#usedebugvalue) -## Basic Hooks {#basic-hooks} +## Les Hooks de base {#basic-hooks} ### `useState` {#usestate} @@ -33,29 +33,29 @@ If you're new to Hooks, you might want to check out [the overview](/docs/hooks-o const [state, setState] = useState(initialState); ``` -Returns a stateful value, and a function to update it. +Renvoie une valeur d'état local et une fonction pour la mettre à jour. -During the initial render, the returned state (`state`) is the same as the value passed as the first argument (`initialState`). +Pendant le rendu initial, l'état local (`state`) a la même valeur que celle passée en premier argument (`initialState`). -The `setState` function is used to update the state. It accepts a new state value and enqueues a re-render of the component. +La fonction `setState` permet de mettre à jour l'état local. Elle accepte une nouvelle valeur d'état local et planifie un nouveau rendu du composant. ```js setState(newState); ``` -During subsequent re-renders, the first value returned by `useState` will always be the most recent state after applying updates. +Au cours des rendus suivants, la première valeur renvoyée par `useState` sera toujours celle de l'état local le plus récent, une fois les mises à jour effectuées. -#### Functional updates {#functional-updates} +#### Mises à jour fonctionnelles {#functional-updates} -If the new state is computed using the previous state, you can pass a function to `setState`. The function will receive the previous value, and return an updated value. Here's an example of a counter component that uses both forms of `setState`: +Si le nouvel état local est déduit de l'état local précédent, vous pouvez passer une fonction à `setState`. Cette fonction recevra la valeur précédente de l'état local et renverra une nouvelle valeur de l'état local. Voici un exemple d'un composant compteur qui utilise les deux formes de `setState` : ```js function Counter({initialCount}) { const [count, setCount] = useState(initialCount); return ( <> - Count: {count} - + Total : {count} + @@ -63,24 +63,24 @@ function Counter({initialCount}) { } ``` -The "+" and "-" buttons use the functional form, because the updated value is based on the previous value. But the "Reset" button uses the normal form, because it always sets the count back to 0. +Les boutons « + » et « - » utilisent la forme fonctionnelle, puisque la nouvelle valeur est calculée à partir de la valeur précédente. Le bouton « Réinitialiser » utilise quant à lui la forme normale puisqu'il remet toujours le total à une valeur fixe. -> Note +> Remarque > -> Unlike the `setState` method found in class components, `useState` does not automatically merge update objects. You can replicate this behavior by combining the function updater form with object spread syntax: +> À l'inverse de la méthode `setState` que l'on trouve dans les composants définis à l'aide d'une classe, `useState` ne fusionne pas automatiquement les objets de mise à jour. Vous pouvez imiter ce comportement en combinant la forme fonctionnelle de mise à jour avec la syntaxe de *spread* des objets : > > ```js > setState(prevState => { -> // Object.assign would also work +> // Object.assign marcherait aussi > return {...prevState, ...updatedValues}; > }); > ``` > -> Another option is `useReducer`, which is more suited for managing state objects that contain multiple sub-values. +> Il est aussi possible d'utiliser `userReducer`, qui est plus adapté pour gérer les objets d'état local qui contiennent plusieurs sous-valeurs. -#### Lazy initial state {#lazy-initial-state} +#### État local initial paresseux {#lazy-initial-state} -The `initialState` argument is the state used during the initial render. In subsequent renders, it is disregarded. If the initial state is the result of an expensive computation, you may provide a function instead, which will be executed only on the initial render: +Le rendu initial utilise l'argument `initialState` comme état local. Au cours des rendus suivants, il est ignoré. Si l'état local initial est le résultat d'un calcul coûteux, vous pouvez plutôt fournir une fonction qui sera executée seulement au cours du rendu initial : ```js const [state, setState] = useState(() => { @@ -89,9 +89,9 @@ const [state, setState] = useState(() => { }); ``` -#### Bailing out of a state update {#bailing-out-of-a-state-update} +#### Abandon de la mise à jour de l'état local {#bailing-out-of-a-state-update} -If you update a State Hook to the same value as the current state, React will bail out without rendering the children or firing effects. (React uses the [`Object.is` comparison algorithm](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is#Description).) +Si vous mettez à jour un Hook d'état avec la même valeur que son état actuel, React abandonnera cette mise à jour, ce qui signifie qu'aucun nouveau rendu des enfants ne sera effectué et qu'aucun effet ne sera déclenché. (React utilise [l'algorithme de comparaison `Object.is`](https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/Object/is).) ### `useEffect` {#useeffect} @@ -99,45 +99,44 @@ If you update a State Hook to the same value as the current state, React will ba useEffect(didUpdate); ``` -Accepts a function that contains imperative, possibly effectful code. +Accepte une fonction qui contient du code impératif, pouvant éventuellement produire des effets. -Mutations, subscriptions, timers, logging, and other side effects are not allowed inside the main body of a function component (referred to as React's _render phase_). Doing so will lead to confusing bugs and inconsistencies in the UI. +L'utilisation de mutations, abonnements, horloges, messages de journalisation, et autres effets de bord n'est pas autorisée au sein du corps principal d'une fonction composant (qu'on appelle la _phase de rendu_ de React). Autrement ça pourrait entraîner des bugs déconcertants et des incohérences dans l'interface utilisateur (UI). -Instead, use `useEffect`. The function passed to `useEffect` will run after the render is committed to the screen. Think of effects as an escape hatch from React's purely functional world into the imperative world. + Pour ce faire, utilisez plutôt `useEffect`. La fonction fournie à `useEffect` sera exécutée après que le rendu est apparu sur l'écran. Vous pouvez considérer les effets comme des échappatoires pour passer du monde purement fonctionnel de React au monde impératif. -By default, effects run after every completed render, but you can choose to fire it [only when certain values have changed](#conditionally-firing-an-effect). +Par défaut, les effets de bord s'exécutent après chaque rendu, mais vous pouvez choisir d'en exécuter certains [uniquement quand certaines valeurs ont changé](#conditionally-firing-an-effect). -#### Cleaning up an effect {#cleaning-up-an-effect} +#### Nettoyage d'un effet de bord {#cleaning-up-an-effect} -Often, effects create resources that need to be cleaned up before the component leaves the screen, such as a subscription or timer ID. To do this, the function passed to `useEffect` may return a clean-up function. For example, to create a subscription: +Souvent, les effets de bord créent des ressources qui nécessitent d'être nettoyées avant que le composant ne quitte l'écran, telles qu'un abonnement ou l'ID d'une horloge. Pour ce faire, la fonction fournie à `useEffect` peut renvoyer une fonction de nettoyage. Par exemple, pour créer un abonnement : ```js useEffect(() => { const subscription = props.source.subscribe(); return () => { - // Clean up the subscription + // Nettoyage de l'abonnement subscription.unsubscribe(); }; }); ``` +La fonction de nettoyage est exécutée avant que le composant ne soit retiré de l'UI pour éviter les fuites de mémoire. Par ailleurs, si un composant s’affiche plusieurs fois (comme c'est typiquement le cas), **l'effet de bord précédent est nettoyé avant l'exécution du prochain effet de bord**. Dans notre exemple, ça veut dire qu'un nouvel abonnement est créé à chaque mise à jour. Pour éviter d'exécuter un effet de bord à chaque mise à jour, voyez la section sur l’exécution conditionnelle un peu plus loin. -The clean-up function runs before the component is removed from the UI to prevent memory leaks. Additionally, if a component renders multiple times (as they typically do), the **previous effect is cleaned up before executing the next effect**. In our example, this means a new subscription is created on every update. To avoid firing an effect on every update, refer to the next section. +#### Moment d'exécution des effets de bord {#timing-of-effects} -#### Timing of effects {#timing-of-effects} +Contrairement à `componentDidMount` et `componentDidUpdate`, la fonction fournie à `useEffect` est exécutée de façon différée, **après** la mise en page et l’affichage. `useEffect` est donc bien adapté pour une grande partie des effets de bord, comme la mise en place d'abonnements et de gestionnaires d'événements, puisque la plupart des types de tâche ne devraient pas gêner la mise à jour de l'affichage par le navigateur. -Unlike `componentDidMount` and `componentDidUpdate`, the function passed to `useEffect` fires **after** layout and paint, during a deferred event. This makes it suitable for the many common side effects, like setting up subscriptions and event handlers, because most types of work shouldn't block the browser from updating the screen. +Cependant, tous les effets de bord ne peuvent pas être différés. Par exemple, une mutation du DOM qui est visible pour l'utilisateur doit s'exécuter de manière synchrone avant l’affichage suivant, afin que l'utilisateur ne puisse pas percevoir une incohérence visuelle. (La distinction est conceptuellement similaire à celle entre écouteur d'événement passif et actif.) Pour ces types d'effets de bord, React fournit un Hook supplémentaire appelé [`useLayoutEffect`](#uselayouteffect). Il a la même signature que `useEffect`, et s'en distingue seulement par le moment où il s'exécute. -However, not all effects can be deferred. For example, a DOM mutation that is visible to the user must fire synchronously before the next paint so that the user does not perceive a visual inconsistency. (The distinction is conceptually similar to passive versus active event listeners.) For these types of effects, React provides one additional Hook called [`useLayoutEffect`](#uselayouteffect). It has the same signature as `useEffect`, and only differs in when it is fired. +Bien que `useEffect` soit différé jusqu'à ce que le navigateur ait terminé l’affichage, son exécution est garantie avant les rendus ultérieurs. React traitera toujours les effets de bord des rendus précédents avant de commencer une nouvelle mise à jour. -Although `useEffect` is deferred until after the browser has painted, it's guaranteed to fire before any new renders. React will always flush a previous render's effects before starting a new update. +#### Exécution conditionnelle d'un effet de bord {#conditionally-firing-an-effect} -#### Conditionally firing an effect {#conditionally-firing-an-effect} +Le comportement par défaut des effets de bord consiste à exécuter l'effet après chaque affichage. Ainsi, un effet est toujours recréé si une de ses entrées (les données dont il dépend) change. -The default behavior for effects is to fire the effect after every completed render. That way an effect is always recreated if one of its inputs changes. +Cependant, ça pourrait être exagéré dans certains cas, comme dans l'exemple avec l'abonnement dans la section précédente. On n’a pas besoin d’un nouvel abonnement à chaque mise à jour, mais seulement si la prop `source` a changé. -However, this may be overkill in some cases, like the subscription example from the previous section. We don't need to create a new subscription on every update, only if the `source` props has changed. - -To implement this, pass a second argument to `useEffect` that is the array of values that the effect depends on. Our updated example now looks like this: +Pour mettre ça en œuvre, fournissez un deuxième argument à `useEffect` qui consiste en un tableau de valeurs dont l'effet dépend. Notre exemple mis à jour ressemble maintenant à ça : ```js useEffect( @@ -151,13 +150,13 @@ useEffect( ); ``` -Now the subscription will only be recreated when `props.source` changes. +L'abonnement sera maintenant recréé uniquement quand `props.source` change. -Passing in an empty array `[]` of inputs tells React that your effect doesn't depend on any values from the component, so that effect would run only on mount and clean up on unmount; it won't run on updates. +Fournir un tableau vide `[]` d'entrées indique à React que votre effet ne dépend d'aucune valeur du composant, du coup l'effet ne s'exécuterait que lors du montage et ne se nettoierait qu’au démontage ; il ne s'exécuterait pas lors des mises à jour. -> Note +> Remarque > -> The array of inputs is not passed as arguments to the effect function. Conceptually, though, that's what they represent: every value referenced inside the effect function should also appear in the inputs array. In the future, a sufficiently advanced compiler could create this array automatically. +> Le tableau d'entrées n'est pas fourni comme argument à la fonction d'effet. Conceptuellement cependant, c'est en quelque sorte ce qui se passe : chaque valeur référencée dans la fonction d'effet devrait aussi apparaître dans le tableau d'entrées. À l'avenir, un compilateur suffisamment avancé pourrait créer ce tableau automatiquement. ### `useContext` {#usecontext} @@ -165,13 +164,13 @@ Passing in an empty array `[]` of inputs tells React that your effect doesn't de const context = useContext(Context); ``` -Accepts a context object (the value returned from `React.createContext`) and returns the current context value, as given by the nearest context provider for the given context. +Accepte un objet contexte (la valeur renvoyée par `React.createContext`), et renvoie la valeur actuelle du contexte telle qu'elle est donnée par le fournisseur de contexte le plus proche pour l’objet contexte utilisé. -When the provider updates, this Hook will trigger a rerender with the latest context value. +Quand le fournisseur met la valeur à jour, ce Hook va déclencher un nouveau rendu avec la valeur la plus récente du contexte. -## Additional Hooks {#additional-hooks} +## Hooks supplémentaires {#additional-hooks} -The following Hooks are either variants of the basic ones from the previous section, or only needed for specific edge cases. Don't stress about learning them up front. +Les Hooks qui suivent sont soit des variantes des Hooks basiques des sections précédentes, soit seulement nécessaires pour des cas à la marge spécifiques. Ne vous sentez pas obligé·e de les apprendre dès le départ. ### `useReducer` {#usereducer} @@ -179,11 +178,11 @@ The following Hooks are either variants of the basic ones from the previous sect const [state, dispatch] = useReducer(reducer, initialArg, init); ``` -An alternative to [`useState`](#usestate). Accepts a reducer of type `(state, action) => newState`, and returns the current state paired with a `dispatch` method. (If you're familiar with Redux, you already know how this works.) +Alternative à [`useState`](#usestate). Accepte un réducteur de type `(state, action) => newState`, et renvoie l'état local actuel accompagné d'une méthode `dispatch`. (Si vous avez l’habitude de Redux, vous savez déjà comment ça fonctionne.) -`useReducer` is usually preferable to `useState` when you have complex state logic that involves multiple sub-values or when the next state depends on the previous one. `useReducer` also lets you optimize performance for components that trigger deep updates because [you can pass `dispatch` down instead of callbacks](/docs/hooks-faq.html#how-to-avoid-passing-callbacks-down). +`useReducer` est souvent préférable à `useState` quand vous avez une logique d'état local complexe qui comprend plusieurs sous-valeurs, ou quand l'état suivant dépend de l'état précédent. `useReducer` vous permet aussi d'optimiser les performances pour des composants qui déclenchent des mises à jours profondes puisque [vous pouvez fournir `dispatch` à la place de fonctions de rappel](/docs/hooks-faq.html#how-to-avoid-passing-callbacks-down). -Here's the counter example from the [`useState`](#usestate) section, rewritten to use a reducer: +Voici l'exemple du composant compteur du paragraphe [`useState`](#usestate) ré-écrit avec un réducteur : ```js const initialState = {count: 0}; @@ -203,7 +202,7 @@ function Counter({initialState}) { const [state, dispatch] = useReducer(reducer, initialState); return ( <> - Count: {state.count} + Total : {state.count} @@ -211,9 +210,9 @@ function Counter({initialState}) { } ``` -#### Specifying the initial state {#specifying-the-initial-state} +#### Préciser l'état local initial {#specifying-the-initial-state} -There’s two different ways to initialize `useReducer` state. You may choose either one depending on the use case. The simplest way to pass the initial state as a second argument: +Il existe deux manières différentes d'initialiser l'état de `useReducer`. Vous pouvez choisir l'une ou l'autre suivant le cas. La manière la plus simple consiste à fournir l'état initial comme deuxième argument : ```js{3} const [state, dispatch] = useReducer( @@ -222,15 +221,15 @@ There’s two different ways to initialize `useReducer` state. You may choose ei ); ``` ->Note +>Remarque > ->React doesn’t use the `state = initialState` argument convention popularized by Redux. The initial value sometimes needs to depend on props and so is specified from the Hook call instead. If you feel strongly about this, you can call `useReducer(reducer, undefined, reducer)` to emulate the Redux behavior, but it's not encouraged. +>React n'utilise pas la convention d'argument `state = initialState` popularisée par Redux. La valeur initiale doit parfois dépendre de props et c’est donc plutôt l'appel du Hook qui la précise. Si vous avez déjà une préférence bien arrêtée là-dessus, vous pouvez utiliser `useReducer(reducer, undefined, reducer)` pour simuler le comportement de Redux, mais nous ne vous le conseillons pas. -#### Lazy initialization {#lazy-initialization} +#### Initialisation paresseuse {#lazy-initialization} -You can also create the initial state lazily. To do this, you can pass an `init` function as the third argument. The initial state will be set to `init(initialArg)`. +Vous pouvez aussi créer l'état local initial paresseusement. Pour ce faire, vous pouvez fournir une fonction `init` comme troisième argument. L'état initial sera alors égal à `init(initialArg)`. -It lets you extract the logic for calculating the initial state outside the reducer. This is also handy for resetting the state later in response to an action: +Ça vous permet d'extraire la logique pour calculer l'état local initial hors du réducteur. C'est aussi pratique pour réinitialiser l'état local en réponse à une action ultérieure : ```js{1-3,11-12,19,24} function init(initialCount) { @@ -254,7 +253,7 @@ function Counter({initialCount}) { const [state, dispatch] = useReducer(reducer, initialCount, init); return ( <> - Count: {state.count} + Total : {state.count} + ); } ``` -Note that `useRef()` is useful for more than the `ref` attribute. It's [handy for keeping any mutable value around](/docs/hooks-faq.html#is-there-something-like-instance-variables) similar to how you'd use instance fields in classes. +Remarquez que `useRef()` est utile au-delà du seul attribut `ref`. C'est [pratique pour garder des valeurs modifiables sous la main](/docs/hooks-faq.html#is-there-something-like-instance-variables), comme lorsque vous utilisez des champs d’instance dans les classes. ### `useImperativeHandle` {#useimperativehandle} @@ -345,7 +345,7 @@ Note that `useRef()` is useful for more than the `ref` attribute. It's [handy fo useImperativeHandle(ref, createHandle, [inputs]) ``` -`useImperativeHandle` customizes the instance value that is exposed to parent components when using `ref`. As always, imperative code using refs should be avoided in most cases. `useImperativeHandle` should be used with `forwardRef`: +`useImperativeHandle` personnalise l'instance qui est exposée au composant parent lors de l'utilisation de `ref`. Comme toujours, il vaut mieux s'abstenir d'utiliser du code impératif manipulant des refs dans la plupart des cas. `useImperativeHandle` est conçu pour être utilisé en conjonction avec `forwardRef` : ```js function FancyInput(props, ref) { @@ -359,18 +359,17 @@ function FancyInput(props, ref) { } FancyInput = forwardRef(FancyInput); ``` - -In this example, a parent component that renders `` would be able to call `fancyInputRef.current.focus()`. +Dans cet exemple, un composant parent qui utiliserait `` pourrait appeler `fancyInputRef.current.focus()`. ### `useLayoutEffect` {#uselayouteffect} -The signature is identical to `useEffect`, but it fires synchronously after all DOM mutations. Use this to read layout from the DOM and synchronously re-render. Updates scheduled inside `useLayoutEffect` will be flushed synchronously, before the browser has a chance to paint. +La signature est identique à celle de `useEffect`, mais `useLayoutEffect` s'exécute de manière synchrone après que toutes les mutations du DOM ont eu lieu. Utilisez-le pour inspecter la mise en page du DOM et effectuer un nouveau rendu de manière synchrone. Les mises à jour planifiées dans `useLayoutEffect` seront traitées de manière synchrone avant que le navigateur ait pu procéder à l’affichage. -Prefer the standard `useEffect` when possible to avoid blocking visual updates. +Préférez l'utilisation du `useEffect` standard chaque fois que possible, pour éviter de bloquer les mises à jour visuelles. -> Tip +> Astuce > -> If you're migrating code from a class component, `useLayoutEffect` fires in the same phase as `componentDidMount` and `componentDidUpdate`, so if you're unsure of which effect Hook to use, it's probably the least risky. +> Si vous migrez du code depuis un composant écrit à l'aide d'une classe, `useLayoutEffect` s'exécute dans la même phase que `componentDidMount` et `componentDidUpdate`. Si vous n'êtes donc pas sûr·e du Hook d'effet à utiliser, c'est probablement le moins risqué. ### `useDebugValue` {#usedebugvalue} @@ -378,9 +377,9 @@ Prefer the standard `useEffect` when possible to avoid blocking visual updates. useDebugValue(value) ``` -`useDebugValue` can be used to display a label for custom hooks in React DevTools. +Vous pouvez utiliser `useDebugValue` pour afficher une étiquette pour les Hooks personnalisés dans les outils de développement React *(React DevTools, NdT)*. -For example, consider the `useFriendStatus` custom Hook described in ["Building Your Own Hooks"](/docs/hooks-custom.html): +Par exemple, prenez le hook personnalisé `useFriendStatus` décrit dans [« Construire vos propres Hooks »](/docs/hooks-custom.html) : ```js{6-8} function useFriendStatus(friendID) { @@ -388,25 +387,25 @@ function useFriendStatus(friendID) { // ... - // Show a label in DevTools next to this Hook - // e.g. "FriendStatus: Online" - useDebugValue(isOnline ? 'Online' : 'Offline'); + // Affiche une étiquette dans les DevTools à côté de ce Hook + // par exemple, "FriendStatus: En ligne" + useDebugValue(isOnline ? 'En ligne' : 'Hors-ligne'); return isOnline; } ``` -> Tip +> Astuce > -> We don't recommend adding debug values to every custom Hook. It's most valuable for custom Hooks that are part of shared libraries. +> Nous déconseillons d'ajouter ces étiquettes à chaque Hook personnalisé. C'est surtout utile pour les Hooks personnalisés provenant de bibliothèques partagées. -#### Defer formatting debug values {#defer-formatting-debug-values} +#### Différer le formatage des valeurs de débogage {#defer-formatting-debug-values} -In some cases formatting a value for display might be an expensive operation. It's also unnecessary unless a Hook is actually inspected. +Formater une valeur à afficher peut parfois s’avérer coûteux. C'est par ailleurs inutile tant que le Hook n'est pas effectivement inspecté. -For this reason `useDebugValue` accepts a formatting function as an optional second parameter. This function is only called if the Hooks are inspected. It receives the debug value as a parameter and should return a formatted display value. +C’est pourquoi `useDebugValue` accepte une fonction de formatage comme deuxième argument optionnel. Cette fonction est appelée uniquement si les Hooks sont inspectés. Elle reçoit la valeur de débogage comme argument et devrait renvoyer la valeur formatée. -For example a custom Hook that returned a `Date` value could avoid calling the `toDateString` function unnecessarily by passing the following formatter: +Par exemple, un Hook personnalisé qui renvoie une valeur `Date` pourrait éviter d'appeler inutilement la fonction `toDateString` en fournissant le formateur suivant : ```js useDebugValue(date, date => date.toDateString());