Introduction aux thunks dans Redux
Dans le chapitre précédent, nous avons mis en place le travail
du serveur, de la base de données et du client pour
l'échange de données. Maintenant, nous devons
établir le dernier pont qui aidera
notre application Redux organisée de manière 'synchrone'
à interagir avec le client asynchrone
que nous avons créé dans la dernière
leçon du chapitre précédent, afin d'envoyer
des requêtes et de recevoir les données nécessaires en réponse.
Comme nous nous en souvenons depuis les premières leçons de la section
précédente, Redux ne sait rien du travail avec
la logique asynchrone et pour cela, nous utiliserons
le middleware thunk. Ce middleware
permet de travailler avec les actions envoyées,
d'utiliser dans le code de notre thunk les méthodes dispatch et
getState du store, et aussi d'aider
la méthode dispatch à travailler non seulement avec
des objets JS ordinaires, mais aussi avec des entités
telles que des fonctions et des promesses.
Généralement, la fonction thunk est appelée avec deux
arguments dispatch et getState
(si nécessaire), qui peuvent être utilisés
dans le corps de cette fonction. Avec elle, on peut
envoyer des actions ordinaires. On peut aussi
l'envoyer via store.dispatch.
Un exemple d'une telle fonction est donné ci-dessous :
const changeColorThunk = (dispatch, getState) => {
const colorBefore = getState()
console.log(`Old Color: ${colorBefore.color}`)
dispatch(changeColor())
const colorAfter = getState()
console.log(`New Color: ${colorAfter.color}`)
}
store.dispatch(changeColorThunk)
Ouvrons maintenant notre application avec
les produits. La première chose que nous devons obtenir
du serveur au lancement de l'application - c'est
la liste des produits. Comme généralement les thunks
sont écrits dans les fichiers de slice,
nous allons ouvrir le fichier
productsSlice.js.
La bonne nouvelle est que
nous n'avons pas à nous embêter avec l'installation de Redux Thunk,
car la fonction configureStore de RTK
l'aura déjà fait pour nous. Ajoutons donc simplement
createAsyncThunk dans l'import dans le fichier :
import { createSlice, nanoid, createAsyncThunk } from '@reduxjs/toolkit'
Ajoutons également notre client dans l'import :
import { client } from '../../api/client'
Et maintenant, à l'aide de createAsyncThunk,
créeons notre premier thunk pour récupérer
les produits, faisons-le immédiatement après
la déclaration de l'objet initialState :
export const fetchProducts = createAsyncThunk()
Le premier paramètre de createAsyncThunk
sera une chaîne pour le type de l'action générée,
et le second - une fonction de rappel pour
la payload, qui retournera
soit des données, soit une promesse d'erreur (voir
le fichier client.js). Dans le code de la fonction, nous
appelons client.get et lui passons le chemin
que nous avons spécifié sur le serveur (regardez
les paramètres acceptés par http.get dans
server.js) :
export const fetchProducts = createAsyncThunk(
'products/fetchProducts',
async () => {
const response = await client.get('/fakeServer/products')
return response.data
}
)
Ouvrez votre application avec les étudiants.
Ouvrez-y le fichier studentsSlice.js.
Importez-y la fonction createAsyncThunk
pour créer un thunk, ainsi que client pour
envoyer des requêtes API au serveur.
Immédiatement après la déclaration de l'objet initialState,
à l'aide de createAsyncThunk, créez un thunk
fetchStudents pour récupérer la liste des étudiants,
qui enverra une requête GET à
l'adresse /fakeServer/students, spécifiée
dans votre fichier server.js, et retournera
response.data, comme montré dans les matériaux
de la leçon. Comme premier paramètre pour
createAsyncThunk, spécifiez la chaîne
students/fetchStudents pour le type d'action.