diff --git a/src/content/learn/scaling-up-with-reducer-and-context.md b/src/content/learn/scaling-up-with-reducer-and-context.md index 0281afcec..5893364ba 100644 --- a/src/content/learn/scaling-up-with-reducer-and-context.md +++ b/src/content/learn/scaling-up-with-reducer-and-context.md @@ -1,24 +1,24 @@ --- -title: Scaling Up with Reducer and Context +title: Mise à l'échelle en combinant réducteur et contexte --- -Reducers let you consolidate a component's state update logic. Context lets you pass information deep down to other components. You can combine reducers and context together to manage state of a complex screen. +Les réducteurs vous permettent de consolider la logique de mise à jour de l'état d'un composant. Le contexte vous offre la possibilité de transmettre de l'information en profondeur à d'autres composants. Vous pouvez les combiner afin de gérer l'état d'un écran complexe. -* How to combine a reducer with context -* How to avoid passing state and dispatch through props -* How to keep context and state logic in a separate file +* Comment combiner un réducteur avec un contexte +* Comment éviter de passer l'état et le *dispatcher* au travers des props +* Comment conserver le contexte et la logique d'état dans un fichier séparé -## Combining a reducer with context {/*combining-a-reducer-with-context*/} +## Combiner un réducteur avec un contexte {/*combining-a-reducer-with-context*/} -In this example from [the introduction to reducers](/learn/extracting-state-logic-into-a-reducer), the state is managed by a reducer. The reducer function contains all of the state update logic and is declared at the bottom of this file: +Dans cet exemple provenant de [l'introduction aux réducteurs](/learn/extracting-state-logic-into-a-reducer), l'état est géré par un réducteur. Cette fonction (déclarée à la fin du fichier) contient toute la logique de mise à jour de l'état : @@ -57,7 +57,7 @@ export default function TaskApp() { return ( <> -

Day off in Kyoto

+

Jour de repos à Kyoto

@@ -99,9 +99,9 @@ function tasksReducer(tasks, action) { let nextId = 3; const initialTasks = [ - { id: 0, text: 'Philosopher’s Path', done: true }, - { id: 1, text: 'Visit the temple', done: false }, - { id: 2, text: 'Drink matcha', done: false } + { id: 0, text: 'La promenade du philosophe', done: true }, + { id: 1, text: 'Visiter le temple', done: false }, + { id: 2, text: 'Boire du thé matcha', done: false } ]; ``` @@ -113,14 +113,14 @@ export default function AddTask({ onAddTask }) { return ( <> setText(e.target.value)} /> + }}>Ajouter ) } @@ -164,7 +164,7 @@ function Task({ task, onChange, onDelete }) { }); }} /> ); @@ -173,7 +173,7 @@ function Task({ task, onChange, onDelete }) { <> {task.text} ); @@ -192,7 +192,7 @@ function Task({ task, onChange, onDelete }) { /> {taskContent} ); @@ -207,9 +207,9 @@ ul, li { margin: 0; padding: 0; }
-A reducer helps keep the event handlers short and concise. However, as your app grows, you might run into another difficulty. **Currently, the `tasks` state and the `dispatch` function are only available in the top-level `TaskApp` component.** To let other components read the list of tasks or change it, you have to explicitly [pass down](/learn/passing-props-to-a-component) the current state and the event handlers that change it as props. +Un réducteur permet de garder les gestionnaires d'événements concis. Vous pouvez cependant rencontrer une autre difficulté à mesure que votre appli grandit. **Pour le moment, l'état `tasks` et le fonction `dispatch` ne sont disponibles qu'au niveau du composant racine `TaskApp`.** Pour que les autres composants puissent lire ou modifier la liste de tâches, vous devez explicitement [transmettre](/learn/passing-props-to-a-component) *via* les props l'état courant et les gestionnaires d'événements qui le modifient. -For example, `TaskApp` passes a list of tasks and the event handlers to `TaskList`: +Par exemple, `TaskApp` passe une liste de tâches et les gestionnaires d'événements à `TaskList` : ```js ``` -And `TaskList` passes the event handlers to `Task`: +Et `TaskList` passe les gestionnaires d'événements à `Task` : ```js ``` -In a small example like this, this works well, but if you have tens or hundreds of components in the middle, passing down all state and functions can be quite frustrating! +Ça fonctionne bien pour un petit exemple comme celui-là, mais si vous avez des dizaines voire des centaines de composants au milieu, transmettre les états et gestionnaires d'événements peut s'avérer plutôt frustrant ! -This is why, as an alternative to passing them through props, you might want to put both the `tasks` state and the `dispatch` function [into context.](/learn/passing-data-deeply-with-context) **This way, any component below `TaskApp` in the tree can read the tasks and dispatch actions without the repetitive "prop drilling".** +C'est pourquoi, plutôt que de les passer *via* les props, vous pourriez mettre l'état `tasks` et la fonction `dispatch` [dans un contexte](/learn/passing-data-deeply-with-context). **De cette façon, tous les composants en dessous de `TaskApp` dans l'arbre peuvent lire les tâches et *dispatcher* les actions sans la « percolation des props ».** -Here is how you can combine a reducer with context: +Voici comment vous pouvez combiner un réducteur avec un contexte : -1. **Create** the context. -2. **Put** state and dispatch into context. -3. **Use** context anywhere in the tree. +1. **Créez** le contexte. +2. **Mettez** l'état et la fonction de *dispatch* dans le contexte. +3. **Utilisez** le contexte n'importe où dans l'arbre. -### Step 1: Create the context {/*step-1-create-the-context*/} +### Étape 1 : créer le contexte {/*step-1-create-the-context*/} -The `useReducer` Hook returns the current `tasks` and the `dispatch` function that lets you update them: +Le Hook `useReducer` renvoie les `tasks` courantes, ainsi que la fonction `dispatch` qui vous permet de les mettre à jour : ```js const [tasks, dispatch] = useReducer(tasksReducer, initialTasks); ``` -To pass them down the tree, you will [create](/learn/passing-data-deeply-with-context#step-2-use-the-context) two separate contexts: +Pour les passer à travers l'arbre, vous aller [créer](/learn/passing-data-deeply-with-context#step-2-use-the-context) deux contextes distincts : -- `TasksContext` provides the current list of tasks. -- `TasksDispatchContext` provides the function that lets components dispatch actions. +- `TasksContext` fournit la liste actuelle des tâches. +- `TasksDispatchContext` fournit la fonction qui permet aux composants de *dispatcher* les actions. -Export them from a separate file so that you can later import them from other files: +Exportez-les à partir d'un fichier dédié de façon à pouvoir les importer ultérieurement dans d'autres fichiers : @@ -291,7 +291,7 @@ export default function TaskApp() { return ( <> -

Day off in Kyoto

+

Jour de repos à Kyoto

@@ -333,9 +333,9 @@ function tasksReducer(tasks, action) { let nextId = 3; const initialTasks = [ - { id: 0, text: 'Philosopher’s Path', done: true }, - { id: 1, text: 'Visit the temple', done: false }, - { id: 2, text: 'Drink matcha', done: false } + { id: 0, text: 'La promenade du philosophe', done: true }, + { id: 1, text: 'Visiter le temple', done: false }, + { id: 2, text: 'Boire du thé matcha', done: false } ]; ``` @@ -354,14 +354,14 @@ export default function AddTask({ onAddTask }) { return ( <> setText(e.target.value)} /> + }}>Ajouter ) } @@ -405,7 +405,7 @@ function Task({ task, onChange, onDelete }) { }); }} /> ); @@ -414,7 +414,7 @@ function Task({ task, onChange, onDelete }) { <> {task.text} ); @@ -433,7 +433,7 @@ function Task({ task, onChange, onDelete }) { /> {taskContent} ); @@ -448,11 +448,11 @@ ul, li { margin: 0; padding: 0; }
-Here, you're passing `null` as the default value to both contexts. The actual values will be provided by the `TaskApp` component. +Ici, vous passez `null` comme valeur par défaut aux deux contextes. Les valeurs réelles seront fournies par le composant `TaskApp`. -### Step 2: Put state and dispatch into context {/*step-2-put-state-and-dispatch-into-context*/} +### Étape 2 : placer l'état et le *dispatch* dans le contexte {/*step-2-put-state-and-dispatch-into-context*/} -Now you can import both contexts in your `TaskApp` component. Take the `tasks` and `dispatch` returned by `useReducer()` and [provide them](/learn/passing-data-deeply-with-context#step-3-provide-the-context) to the entire tree below: +Vous pouvez maintenant importer les deux contextes dans votre composant `TaskApp`. Prenez les `tasks` et `dispatch` renvoyées par le `useReducer()` et [fournissez-les](/learn/passing-data-deeply-with-context#step-3-provide-the-context) à l'arbre entier en dessous : ```js {4,7-8} import { TasksContext, TasksDispatchContext } from './TasksContext.js'; @@ -470,7 +470,7 @@ export default function TaskApp() { } ``` -For now, you pass the information both via props and in context: +Pour l'instant, vous passez l'information à la fois par les props et dans le contexte : @@ -511,7 +511,7 @@ export default function TaskApp() { return ( -

Day off in Kyoto

+

Jour de repos à Kyoto

@@ -554,9 +554,9 @@ function tasksReducer(tasks, action) { let nextId = 3; const initialTasks = [ - { id: 0, text: 'Philosopher’s Path', done: true }, - { id: 1, text: 'Visit the temple', done: false }, - { id: 2, text: 'Drink matcha', done: false } + { id: 0, text: 'La promenade du philosophe', done: true }, + { id: 1, text: 'Visiter le temple', done: false }, + { id: 2, text: 'Boire du thé matcha', done: false } ]; ``` @@ -575,14 +575,14 @@ export default function AddTask({ onAddTask }) { return ( <> setText(e.target.value)} /> + }}>Ajouter ) } @@ -626,7 +626,7 @@ function Task({ task, onChange, onDelete }) { }); }} /> ); @@ -635,7 +635,7 @@ function Task({ task, onChange, onDelete }) { <> {task.text} ); @@ -654,7 +654,7 @@ function Task({ task, onChange, onDelete }) { /> {taskContent} ); @@ -669,23 +669,23 @@ ul, li { margin: 0; padding: 0; }
-In the next step, you will remove prop passing. +Vous cesserez d'utiliser les props dans la prochaine étape. -### Step 3: Use context anywhere in the tree {/*step-3-use-context-anywhere-in-the-tree*/} +### Étape 3 : utiliser un contexte n'importe où dans l'arbre {/*step-3-use-context-anywhere-in-the-tree*/} -Now you don't need to pass the list of tasks or the event handlers down the tree: +Vous n'avez désormais plus besoin de passer la liste de tâches ou les gestionnaires d'événements à travers l'arbre à coups de props : ```js {4-5} -

Day off in Kyoto

+

Jour de repos à Kyoto

``` -Instead, any component that needs the task list can read it from the `TaskContext`: +Au lieu de ça, un composant qui a besoin de la liste de tâches peut la lire depuis le `TaskContext` : ```js {2} export default function TaskList() { @@ -693,7 +693,7 @@ export default function TaskList() { // ... ``` -To update the task list, any component can read the `dispatch` function from context and call it: +Pour mettre à jour la liste de tâches, un composant peut lire la fonction `dispatch` depuis le contexte approprié, puis l'appeler : ```js {3,9-13} export default function AddTask() { @@ -709,11 +709,11 @@ export default function AddTask() { id: nextId++, text: text, }); - }}>Add + }}>Ajouter // ... ``` -**The `TaskApp` component does not pass any event handlers down, and the `TaskList` does not pass any event handlers to the `Task` component either.** Each component reads the context that it needs: +**Le composant `TaskApp` ne transmet aucun gestionnaire d'événement à ses enfants, et la `TaskList` ne transmet pas non plus de gestionnaire d'événement au composant `Task`.** Chaque composant lit le contexte dont il a besoin : @@ -732,7 +732,7 @@ export default function TaskApp() { return ( -

Day off in Kyoto

+

Jour de repos à Kyoto

@@ -768,9 +768,9 @@ function tasksReducer(tasks, action) { } const initialTasks = [ - { id: 0, text: 'Philosopher’s Path', done: true }, - { id: 1, text: 'Visit the temple', done: false }, - { id: 2, text: 'Drink matcha', done: false } + { id: 0, text: 'La promenade du philosophe', done: true }, + { id: 1, text: 'Visiter le temple', done: false }, + { id: 2, text: 'Boire du thé matcha', done: false } ]; ``` @@ -791,7 +791,7 @@ export default function AddTask() { return ( <> setText(e.target.value)} /> @@ -801,8 +801,8 @@ export default function AddTask() { type: 'added', id: nextId++, text: text, - }); - }}>Add + }); + }}>Ajouter ); } @@ -846,7 +846,7 @@ function Task({ task }) { }); }} /> ); @@ -855,7 +855,7 @@ function Task({ task }) { <> {task.text} ); @@ -882,7 +882,7 @@ function Task({ task }) { id: task.id }); }}> - Delete + Supprimer ); @@ -897,11 +897,11 @@ ul, li { margin: 0; padding: 0; }
-**The state still "lives" in the top-level `TaskApp` component, managed with `useReducer`.** But its `tasks` and `dispatch` are now available to every component below in the tree by importing and using these contexts. +**L'état « vit » toujours dans le composant de haut-niveau `TaskApp`, où il reste géré avec `useReducer`.** Toutefois, ses `tasks` et `dispatch` sont désormais accessibles à chaque composant plus bas dans l'arbre, en important et utilisant ces contextes. -## Moving all wiring into a single file {/*moving-all-wiring-into-a-single-file*/} +## Déplacer toute cette plomberie dans un seul fichier {/*moving-all-wiring-into-a-single-file*/} -You don't have to do this, but you could further declutter the components by moving both reducer and context into a single file. Currently, `TasksContext.js` contains only two context declarations: +Ça n'a rien d'obligatoire, mais vous pouvez encore alléger les composants en déplaçant le réducteur et le contexte dans un unique fichier distinct. Pour le moment, `TasksContext.js` ne contient que les deux déclarations de contexte : ```js import { createContext } from 'react'; @@ -910,11 +910,11 @@ export const TasksContext = createContext(null); export const TasksDispatchContext = createContext(null); ``` -This file is about to get crowded! You'll move the reducer into that same file. Then you'll declare a new `TasksProvider` component in the same file. This component will tie all the pieces together: +Ce fichier va très vite grandir ! Vous allez déplacer le réducteur dans ce fichier. Ensuite, vous allez y déclarer un nouveau composant `TasksProvider`. Ce composant va relier toutes les pièces du puzzle : -1. It will manage the state with a reducer. -2. It will provide both contexts to components below. -3. It will [take `children` as a prop](/learn/passing-props-to-a-component#passing-jsx-as-children) so you can pass JSX to it. +1. Il gérera l'état avec un réducteur. +2. Il fournira les deux contextes aux composants en dessous. +3. Il [prendra les `children` en tant que props](/learn/passing-props-to-a-component#passing-jsx-as-children) afin que vous puissiez lui donner du JSX. ```js export function TasksProvider({ children }) { @@ -930,7 +930,7 @@ export function TasksProvider({ children }) { } ``` -**This removes all the complexity and wiring from your `TaskApp` component:** +**Ça supprime toute la complexité et la plomberie de votre composant `TaskApp` :** @@ -942,7 +942,7 @@ import { TasksProvider } from './TasksContext.js'; export default function TaskApp() { return ( -

Day off in Kyoto

+

Jour de repos à Kyoto

@@ -999,9 +999,9 @@ function tasksReducer(tasks, action) { } const initialTasks = [ - { id: 0, text: 'Philosopher’s Path', done: true }, - { id: 1, text: 'Visit the temple', done: false }, - { id: 2, text: 'Drink matcha', done: false } + { id: 0, text: 'La promenade du philosophe', done: true }, + { id: 1, text: 'Visiter le temple', done: false }, + { id: 2, text: 'Boire du thé matcha', done: false } ]; ``` @@ -1015,7 +1015,7 @@ export default function AddTask() { return ( <> setText(e.target.value)} /> @@ -1025,8 +1025,8 @@ export default function AddTask() { type: 'added', id: nextId++, text: text, - }); - }}>Add + }); + }}>Ajouter ); } @@ -1070,7 +1070,7 @@ function Task({ task }) { }); }} /> ); @@ -1079,7 +1079,7 @@ function Task({ task }) { <> {task.text} ); @@ -1106,7 +1106,7 @@ function Task({ task }) { id: task.id }); }}> - Delete + Supprimer ); @@ -1121,7 +1121,7 @@ ul, li { margin: 0; padding: 0; }
-You can also export functions that _use_ the context from `TasksContext.js`: +Vous pouvez également exporter des fonctions qui _utilisent_ le contexte de `TasksContext.js` : ```js export function useTasks() { @@ -1133,14 +1133,14 @@ export function useTasksDispatch() { } ``` -When a component needs to read context, it can do it through these functions: +Quand un composant a besoin de lire le contexte, il peut le faire *via* ces fonctions : ```js const tasks = useTasks(); const dispatch = useTasksDispatch(); ``` -This doesn't change the behavior in any way, but it lets you later split these contexts further or add some logic to these functions. **Now all of the context and reducer wiring is in `TasksContext.js`. This keeps the components clean and uncluttered, focused on what they display rather than where they get the data:** +Ça ne change en rien le comportement, mais ça vous laisse l'opportunité de diviser davantage ces contextes ou d'ajouter de la logique à ces fonctions. **Toute la plomberie du contexte et du réducteur se trouvent désormais dans `TasksContext.js`. Ça laisse les composants propres et épurés, et ils peuvent ainsi se concentrer sur ce qu'ils doivent afficher plutôt que savoir où chercher les données :** @@ -1152,7 +1152,7 @@ import { TasksProvider } from './TasksContext.js'; export default function TaskApp() { return ( -

Day off in Kyoto

+

Jour de repos à Kyoto

@@ -1218,9 +1218,9 @@ function tasksReducer(tasks, action) { } const initialTasks = [ - { id: 0, text: 'Philosopher’s Path', done: true }, - { id: 1, text: 'Visit the temple', done: false }, - { id: 2, text: 'Drink matcha', done: false } + { id: 0, text: 'La promenade du philosophe', done: true }, + { id: 1, text: 'Visiter le temple', done: false }, + { id: 2, text: 'Boire du thé matcha', done: false } ]; ``` @@ -1234,7 +1234,7 @@ export default function AddTask() { return ( <> setText(e.target.value)} /> @@ -1244,8 +1244,8 @@ export default function AddTask() { type: 'added', id: nextId++, text: text, - }); - }}>Add + }); + }}>Ajouter ); } @@ -1289,7 +1289,7 @@ function Task({ task }) { }); }} /> ); @@ -1298,7 +1298,7 @@ function Task({ task }) { <> {task.text} ); @@ -1325,7 +1325,7 @@ function Task({ task }) { id: task.id }); }}> - Delete + Supprimer ); @@ -1340,27 +1340,26 @@ ul, li { margin: 0; padding: 0; }
-You can think of `TasksProvider` as a part of the screen that knows how to deal with tasks, `useTasks` as a way to read them, and `useTasksDispatch` as a way to update them from any component below in the tree. +Vous pouvez voir le `TasksProvider` comme une partie de l'écran qui sait comment traiter les tâches, `useTasks` comme une façon de les lire et `useTasksDispatch` comme un moyen de les mettre à jour à partir de n'importe quel composant plus bas dans l'arbre. -Functions like `useTasks` and `useTasksDispatch` are called *[Custom Hooks.](/learn/reusing-logic-with-custom-hooks)* Your function is considered a custom Hook if its name starts with `use`. This lets you use other Hooks, like `useContext`, inside it. +Les fonctions comme `useTasks` et `useTasksDispatch` sont ce qu'on appelle des *[Hooks personnalisés](/learn/reusing-logic-with-custom-hooks)*. Votre fonction est considérée comme un Hook personnalisé si son nom commence par `use`. Vous pouvez alors utiliser d'autres Hooks comme `useContext` à l'intérieur. -As your app grows, you may have many context-reducer pairs like this. This is a powerful way to scale your app and [lift state up](/learn/sharing-state-between-components) without too much work whenever you want to access the data deep in the tree. +Au fur et à mesure que votre appli grandit, il se peut que vous ayez de nombreuses paires contexte-réducteur comme celle-ci. C'est un moyen puissant de faire grandir votre appli et de [faire remonter l'état](/learn/sharing-state-between-components) sans trop d'efforts chaque fois que vous avez besoin d'accéder aux données au plus profond de l'arbre. -- You can combine reducer with context to let any component read and update state above it. -- To provide state and the dispatch function to components below: - 1. Create two contexts (for state and for dispatch functions). - 2. Provide both contexts from the component that uses the reducer. - 3. Use either context from components that need to read them. -- You can further declutter the components by moving all wiring into one file. - - You can export a component like `TasksProvider` that provides context. - - You can also export custom Hooks like `useTasks` and `useTasksDispatch` to read it. -- You can have many context-reducer pairs like this in your app. +- Vous pouvez combiner le réducteur avec le contexte pour permettre à n'importe quel composant de lire et mettre à jour l'état qui se trouve au-dessus de lui. +- Pour fournir l'état et la fonction de *dispatch* aux composants en dessous : + 1. Créez deux contextes (l'un pour l'état et l'autre pour les fonctions de *dispatch*). + 2. Fournissez ces deux contextes à partir du composant qui utilise le réducteur. + 3. Utilisez l'un ou l'autre des contextes pour les composants qui ont besoin de les lire. +- Vous avez la possibilité d'alléger les composants en déplaçant toute la plomberie dans un seul fichier. + - Vous pouvez exporter un composant tel que `TasksProvider` qui fournit le contexte. + - Vous pouvez également exporter des Hooks personnalisés tels que `useTasks` et `useTasksDispatch` pour lire vos contextes spécifiques. +- Vous pouvez disposer de nombreuses paires contexte-réducteur comme ça dans votre appli. -