|
9 | 9 |
|
10 | 10 | Continuons notre travail avec la [version simplifiée Redux](/en/part6/flux_architecture_and_redux#redux-notes) de notre application de notes. |
11 | 11 |
|
12 | | -Pour faciliter notre développement, modifions notre réducteur afin que le store soit initialisé avec un état contenant quelques notes: |
| 12 | +Pour faciliter notre développement, modifions notre reducer afin que le store soit initialisé avec un état contenant quelques notes: |
13 | 13 |
|
14 | 14 | ```js |
15 | 15 | const initialState = [ |
@@ -71,6 +71,119 @@ const App = () => { |
71 | 71 | } |
72 | 72 | ``` |
73 | 73 |
|
| 74 | +Puisque l'attribut <i>name</i> de tous les boutons radio est le même, ils forment un <i>groupe de boutons</i> où une seule option peut être sélectionnée. |
74 | 75 |
|
| 76 | +Les boutons ont un gestionnaire de changement qui imprime actuellement seulement la chaîne associée au bouton cliqué dans la console. |
| 77 | + |
| 78 | +Nous décidons d'implémenter la fonctionnalité de filtre en stockant <i>la valeur du filtre</i> dans le store Redux en plus des notes elles-mêmes. L'état du store devrait ressembler à ceci après avoir effectué ces changements: |
| 79 | + |
| 80 | +```js |
| 81 | +{ |
| 82 | + notes: [ |
| 83 | + { content: 'reducer defines how redux store works', important: true, id: 1}, |
| 84 | + { content: 'state of store can contain any data', important: false, id: 2} |
| 85 | + ], |
| 86 | + filter: 'IMPORTANT' |
| 87 | +} |
| 88 | +``` |
| 89 | + |
| 90 | +Dans l'implémentation actuelle de notre application, seul le tableau de notes est stocké dans l'état. Dans la nouvelle implémentation, l'objet d'état a deux propriétés, <i>notes</i> qui contient le tableau de notes et <i>filter</i> qui contient une chaîne indiquant quelles notes doivent être affichées à l'utilisateur. |
| 91 | + |
| 92 | +### Reducers combinés |
| 93 | + |
| 94 | +Nous pourrions modifier notre reducer actuel pour gérer la nouvelle forme de l'état. Cependant, une meilleure solution dans cette situation est de définir un nouveau reducer séparé pour l'état du filtre: |
| 95 | + |
| 96 | +```js |
| 97 | +const filterReducer = (state = 'ALL', action) => { |
| 98 | + switch (action.type) { |
| 99 | + case 'SET_FILTER': |
| 100 | + return action.payload |
| 101 | + default: |
| 102 | + return state |
| 103 | + } |
| 104 | +} |
| 105 | +``` |
| 106 | + |
| 107 | +Les actions pour changer l'état du filtre ressemblent à ceci: |
| 108 | + |
| 109 | +```js |
| 110 | +{ |
| 111 | + type: 'SET_FILTER', |
| 112 | + payload: 'IMPORTANT' |
| 113 | +} |
| 114 | +``` |
| 115 | + |
| 116 | +Créons également une nouvelle fonction de _créateur d'action_. Nous écrirons le code pour le créateur d'action dans un nouveau module <i>src/reducers/filterReducer.js</i>: |
| 117 | + |
| 118 | +```js |
| 119 | +const filterReducer = (state = 'ALL', action) => { |
| 120 | + // ... |
| 121 | +} |
| 122 | + |
| 123 | +export const filterChange = filter => { |
| 124 | + return { |
| 125 | + type: 'SET_FILTER', |
| 126 | + payload: filter, |
| 127 | + } |
| 128 | +} |
| 129 | + |
| 130 | +export default filterReducer |
| 131 | +``` |
| 132 | + |
| 133 | +Nous pouvons créer le reducer actuel pour notre application en combinant les deux reducers existants avec la fonction [combineReducers](https://redux.js.org/api/combinereducers). |
| 134 | + |
| 135 | +Définissons le reducer combiné dans le fichier <i>main.jsx</i>: |
| 136 | + |
| 137 | +```js |
| 138 | +import React from 'react' |
| 139 | +import ReactDOM from 'react-dom/client' |
| 140 | +import { createStore, combineReducers } from 'redux' // highlight-line |
| 141 | +import { Provider } from 'react-redux' |
| 142 | +import App from './App' |
| 143 | + |
| 144 | +import noteReducer from './reducers/noteReducer' |
| 145 | +import filterReducer from './reducers/filterReducer' // highlight-line |
| 146 | + |
| 147 | + // highlight-start |
| 148 | +const reducer = combineReducers({ |
| 149 | + notes: noteReducer, |
| 150 | + filter: filterReducer |
| 151 | +}) |
| 152 | + // highlight-end |
| 153 | + |
| 154 | +const store = createStore(reducer) // highlight-line |
| 155 | + |
| 156 | +console.log(store.getState()) |
| 157 | + |
| 158 | +/* |
| 159 | +ReactDOM.createRoot(document.getElementById('root')).render( |
| 160 | + <Provider store={store}> |
| 161 | + <App /> |
| 162 | + </Provider> |
| 163 | +)*/ |
| 164 | + |
| 165 | +ReactDOM.createRoot(document.getElementById('root')).render( |
| 166 | + <Provider store={store}> |
| 167 | + <div /> |
| 168 | + </Provider> |
| 169 | +) |
| 170 | +``` |
| 171 | + |
| 172 | +Puisque notre application se casse complètement à ce point, nous rendons un élément <i>div</i> vide au lieu du composant <i>App</i>. |
| 173 | + |
| 174 | +L'état du store est imprimé dans la console: |
| 175 | + |
| 176 | +[console devtools montrant les données du tableau de notes](../../images/6/4e.png) |
| 177 | + |
| 178 | +Comme nous pouvons le voir dans la sortie, le store a exactement la forme que nous voulions! |
| 179 | + |
| 180 | +Examinons de plus près comment le reducer combiné est créé: |
| 181 | + |
| 182 | +```js |
| 183 | +const reducer = combineReducers({ |
| 184 | + notes: noteReducer, |
| 185 | + filter: filterReducer, |
| 186 | +}) |
| 187 | +``` |
75 | 188 |
|
76 | 189 | </div> |
0 commit comments