**Ceci est une ancienne révision du document !**
Stockage de données
Documentation IndexedDB
Documentation localStorage
Documentation sessionStorage
Documentation React-redux
Documentation Redux Toolkit
Redux est une lib de gestion d'état global dans une application React. Cet état est stocké en mémoire mais disparaît lors d'un rechargement de page. Pour le rendre persistant, on peut l'associer aux mécanismes de stockage du navigateur:
sessionStorage
qui conserve les données uniquement le temps de la sessionlocalStorage
qui conserve les données même après la fermeture du navigateurIndexedDB
qui constitue une base de données côté client sans limite de temps
Monter son Redux store
Le store Redux est l’objet qui contient l’état global. Pour le mettre en place, il faut utiliser Redux Toolkit:
- Nous créons des slices (“portions” d’état) contenant des actions. On s'occupe ici du slice de session pour gérer l'authentification.
// src/redux/reducers/sessionSlice.js import { createSlice } from "@reduxjs/toolkit"; const initialState = { data: JSON.parse(sessionStorage.getItem("session")) ?? null }; const sessionSlice = createSlice({ name: "session", initialState, reducers: { setSession(state, action) { const session = action.payload; state.data = session; sessionStorage.setItem("session", JSON.stringify(session)); }, unsetSession(state) { state.data = null; sessionStorage.removeItem("session"); } }, }); export default sessionSlice.reducer; export const { setSession, unsetSession } = sessionSlice.actions;
- Nous combinons les reducers issus des slices via
combineReducers
et configure le store viaconfigureStore
dansredux/index.js
par exemple.
// src/redux/index.js import sessionReducer from "./reducers/sessionSlice"; import { combineReducers } from "redux"; import { configureStore } from "@reduxjs/toolkit"; const rootReducer = combineReducers({ session: sessionReducer }); export const reduxStore = configureStore({ reducer: rootReducer });
On peut aussi exporter toutes les actions du slice dans l'index qui sert de point d'entrée du Redux store (facultatif).
export * from "./reducers/sessionSlice";
- Ce store est passé au
<Provider>
de react-redux qui englobe toute l'application. Pour rester organisé, Nous créons un composantReduxProvider
.
// src/components/app/ReduxProvider/index.jsx import { Provider } from "react-redux"; import { reduxStore } from "../../../redux"; export const ReduxProvider = (props) => { const { children } = props; return ( <Provider store={reduxStore}> {children} </Provider> ); };
// src/App.jsx import { Router } from "./components/app/Router"; import { ReduxProvider } from "./components/app/ReduxProvider"; export const App = () => { return ( <ReduxProvider> <Router /> </ReduxProvider> ); };
Désormais l'état global de Redux est accessible dans n'importe quel fichier utilisé au sein du ReduxProvider
.
Utiliser l'état global
Pour récupérer l'état global, React-redux met à disposition useSelector
.
Maintenant qu'on a les moyens de savoir si une session est ouverte, reprenons nos composants PublicRoutes
et PrivateRoutes
et remplaçons cette condition “test”.
import { Outlet, Navigate } from "react-router-dom"; import { useSelector } from "react-redux"; export const PublicRoutes = () => { const session = useSelector(state => state.session.data); return session ? <Navigate to="/" : <Outlet />; };
import { Outlet, Navigate } from "react-router-dom"; import { useSelector } from "react-redux"; export const PrivateRoutes = () => { const session = useSelector(state => state.session.data); return session ? <Outlet /> : <Navigate to="/login" />; };
Vous êtes maintenant bloqué sur la page Login. Mais tout va bien ! Nous allons essayer de nous connecter.
Utiliser les actions
Reprenons à présent à présent notre requête de connexion et essayons de modifier l'état global avec les actions que nous avons ajoutées à notre slice. Pour cela il faut utiliser useDispatch
.
import { Input } from "../form/Input"; import { useDispatch } from "react-redux"; import { setSession } from "../../../redux"; export const Login = () => { const dispatch = useDispatch(); const handleFormOnSubmit = (e) => { e.preventDefault() // empêche le comportement par défaut du formulaire const data = new FormData(e.target) const values = Object.fromEntries(data.entries()); const request = { method: "POST", body: values, headers: { Accept: "application/json", "Content-Type": "application/json", } }; fetch(`${API_URL}/login`, request) .then(response => response.json()) .then(json => dispatch(setSession(json.data))) .catch(error => console.error(error)); }; return ( // page login ); };
Et voilà vous maîtrisez la base de Redux. Il ne vous reste plus qu'à rajouter une fonction de déconnexion (dans votre page Home par exemple) et vous avez une application avec un système d'authentification fonctionnel.