Les slices de Redux Toolkit permettent de combiner createAction
et createReducer
en un seul appel de fonction. Cela permet donc de définir les actions et le reducer qui va avec, d’un seul coup.
Créez votre premier slice
Pour créer un slice, on utilise la fonction createSlice
de Redux-Toolkit.
Cette dernière attend un objet en paramètre avec différentes propriétés :
name
: le nom du slice (le nom de la fonctionnalité). Ce nom est utilisé comme préfixe pour les noms des actions du slice.initialState
: le state initial du slice.reducers
: un objet qui définit à la fois les actions et la logique du reducer correspondant.
L’objet passé à la propriété reducers
va définir les actions et le reducer : chaque propriété de l’objet correspond à une action, et définit une fonction de mise à jour du state similaire à la fonction addCase
de createReducer
.
import { createSlice } from '@reduxjs/toolkit'
const themeSlice = createSlice({
// le nom du slice
name: 'theme',
// le state initial
initialState: 'light',
// reducers permet de définir les actions et le reducer
reducers: {
// l'action toggle ('theme/toggle')
toggle: (state) => {
return state === 'light' ? 'dark' : 'light'
},
// l'action set ('theme/set')
set: (state, action) => {
return action.payload
},
},
})
Maintenant que notre slice est créé, on va pouvoir extraire le reducer et les actions !
Récupérez le reducer et les actions
La fonction createSlice
retourne un objet avec les propriétés suivantes :
name
: le nom du slice.reducer
: le Reducer créé par Redux-Toolkit.actions
: un objet contenant les action creators.
On va donc déstructurer le slice pour récupérer le reducer et les actions :
// on extrait les actions et le reducer
const { actions, reducer } = themeSlice
// on export chaque action individuellement
export const { set, toggle } = actions
// on export le reducer comme default export
export default reducer
Vous avez peut-être remarqué que le nom des action creators n’est plus le même ( toggleTheme
est devenu toggle
). Il faut donc bien penser à mettre à jour les imports. Une bonne pratique consiste à importer toutes les actions d’un slice avec import * as
; il est ainsi plus facile d’identifier la fonctionnalité à laquelle est rattachée l’action :
import * as themeActions from '../../features/theme'
function Footer() {
const theme = useSelector(selectTheme)
const dispatch = useDispatch()
return (
<FooterContainer>
<EmailInput theme={theme} />
<NightModeButton onClick={() => dispatch(themeActions.toggle())}>
Changer de mode : {theme === 'light' ? '☀️' : '🌙'}
</NightModeButton>
</FooterContainer>
)
}
Transformez le payload
Nous venons de voir que la fonction createSlice
crée automatiquement des action creators pour nous, un peu comme createAction
. Cependant, avec createAction
on peut modifier la manière dont les données sont envoyées au payload
; c’est le cas de l’action freelanceResolved
.
const freelanceResolved = createAction(
'freelance/resolved',
(freelanceId, data) => ({
payload: { freelanceId, data },
})
)
Avec createSlice
, on peut également modifier la manière dont le payload est créé. Pour cela, il faut utiliser un objet au lieu d’une fonction.
const { actions, reducer } = createSlice({
name: 'freelance',
initialState,
reducers: {
resolved: {
// prepare permet de modifier le payload
prepare: (freelanceId, data) => ({
payload: { freelanceId, data },
}),
// la fonction de reducer
reducer: (draft, action) => {
setVoidIfUndefined(draft, action.payload.freelanceId)
if (
draft[action.payload.freelanceId].status === 'pending' ||
draft[action.payload.freelanceId].status === 'updating'
) {
draft[action.payload.freelanceId].data = action.payload.data
draft[action.payload.freelanceId].status = 'resolved'
return
}
return
},
}
// ...
}
})
On peut maintenant utiliser l’action resolved
de la manière suivante :
dispatch(actions.resolved(freelanceId, data))
Voyons, à présent, comment appliquer une fonctionnalité plus avancée :
Vous pouvez retrouver le code de cette vidéo sur la branche P4C3S3-slices du repository à cette adresse.
Exercez-vous
C’est maintenant à votre tour de transformer des createActions
et createReducer
en createSlice
pour les différentes fonctionnalités de l’application.
Comme vous avez pu le constater dans la vidéo ci-dessus, il s’agit surtout de déplacer le code des fonctionnalités existantes.
Une fois le code existant transformé, vous devrez déplacer dans Redux la logique qui manipule les réponses au questionnaire (en utilisant un slice !).
Une fois que vous avez terminé, allez jeter un œil à la version corrigée sur la branche P4C3S4-solution du repository React-Redux-Shiny à cette adresse.
En résumé
Les Slices de Redux-Toolkit permettent de créer actions et reducer d’un seul coup.
Cela permet de définir la logique de chaque fonctionnalité de manière claire, en évitant les copier-coller.
Vous savez maintenant utiliser Redux-Toolkit ! Vous allez pouvoir écrire votre logique Redux plus rapidement grâce à createAction
, createReducer
et aux slices. Mais, avec tout ce code Redux que vous allez écrire, il serait peut-être bon de s’assurer que tout fonctionne correctement, vous ne pensez pas ?
Suivez-moi dans le prochain chapitre pour voir comment on peut mettre en place des tests sur une application React/Redux !