Titre réécrit en : Les routes protégées dans React Route v6 ne se mettent pas à jour lorsque l'utilisateur se connecte
<p>J'essaie de connecter un utilisateur. J'ai un composant de connexion qui reçoit les informations d'identification, puis j'utilise la boîte à outils redux pour stocker l'état et la validation et tout se fait dans userSlice. J'ai un itinéraire protégé qui doit vérifier si l'utilisateur est connecté et si l'utilisateur n'est pas connecté, il ne doit pas accéder à la page de recette que j'ai. Lorsque j'essaie d'accéder à l'utilisateur à partir d'un composant de routage protégé à l'aide du hook useSelecter, il renvoie null au premier rendu, mais renvoie l'utilisateur au deuxième rendu, mais la connexion échoue toujours. Dans les outils de développement Redux, le statut est bien mis à jour. Existe-t-il un moyen d'obtenir l'objet utilisateur lors du premier rendu du composant de routage protégé ? (Comme vous pouvez le voir, j'utilise le hook useEffect et j'ai un tableau de dépendances). </p>
<p>Merci beaucoup pour votre aide.
Merci. </p>
<p>Voici mon code : </p>
<p>Login.js -- Ce fichier est chargé de recevoir les informations d'identification, de distribuer une action à l'aide de useDispatch et de mettre à jour l'état à l'aide de useDispatch. </p>
<pre class="brush:php;toolbar:false;">importer React, { useState } depuis 'react';
importer { loginUser } depuis '../../features/users/userSlice' ;
importer { useSelector, useDispatch } depuis 'react-redux'
importer { useNavigate } depuis 'react-router-dom' ;
exporter la fonction par défaut Login() {
const [email, setEmail] = useState("");
const [mot de passe, setPassword] = useState("");
const user = useSelector(state => state.user.user)
const dispatch = useDispatch()
const naviguer = useNavigate()
retour (
<div>
<entrée
type="texte"
valeur={e-mail}
onChange={(e) => setEmail(e.target.value)}
/>
<entrée
type="mot de passe"
valeur={mot de passe}
onChange={(e) => setPassword(e.target.value)}
/>
<type de bouton="soumettre" onClick={() =>
dispatch(loginUser({email, mot de passe}))
naviguer('/recettes')
}}>soumettre</bouton>
</div>
)
}</pré>
<p>ProtectedRoute.js -- Ce composant garantit que si l'utilisateur n'est pas authentifié, il ne pourra pas se connecter</p>
<pre class="brush:php;toolbar:false;">importer React, { useState, useEffect } depuis "react" ;
importer { Route, Navigate, Outlet } depuis "react-router-dom" ;
importer { useSelector } depuis 'react-redux' ;
exporter la fonction par défaut ProtectedRoute({ enfants }) {
const [ activeUser, setActiveUser ] = useState (faux)
const user = useSelector((state) => state.user);
useEffect(() => {
si (!user.isLoading) {
utilisateur.succès ? setActiveUser(true) : setActiveUser(false)
console.log('utilisateur actif : ' + utilisateuractif)
}
}, [utilisateur])
retour (
activeUser ? <Outlet /> : <Accéder à="/login"/>
)
}</pré>
<p>app.js -- Ce composant contient toutes les routes, y compris les routes protégées. </p>
<pre class="brush:php;toolbar:false;">importer React depuis "react" ;
importer des recettes depuis "./components/recipes/recipes" ;
importer la connexion depuis "./components/users/Login" ;
importer { BrowserRouter, Routes, Route, Navigate } depuis "react-router-dom" ;
importer ProtectedRoute depuis "./utils.js/ProtectedRoute";
const App = () =>
retour (
<div>
<NavigateurRouter>
<Itinéraires>
<Chemin d'itinéraire="/connexion" élément d'index={<Connexion />} />
<Route path="/" element={<Navigate replace to="/login" />}/>
<Élément d'itinéraire={<ProtectedRoute />}>
<Élément d'itinéraire={<Recettes/>} chemin="/recettes" />
</Itinéraire>
</Itinéraires>
</NavigateurRouter>
</div>
);
} ;
exporter l'application par défaut ;</pre>
<p>userSlice.js -- Boîte à outils Redux pour les tranches, et les réducteurs pour les tranches.</p>
<pre class="brush:php;toolbar:false;">import { createSlice, createAsyncThunk } depuis "@reduxjs/toolkit" ;
importer des axios depuis "axios" ;
const loginUrl = 'http://localhost:5000/api/login';
const signupUrl = 'http://localhost:5000/api/signup';
export const loginUser = createAsyncThunk('user/loginUser', async (data) => {
const réponse = attendre axios.post (loginUrl, data);
réponse de retour ;
})
export const signupUser = createAsyncThunk('user/signupUser', async (data) => {
const réponse = attendre axios.post(signupUrl, data);
réponse de retour ;
})
const état initial = {
utilisateur: {},
isLoading : vrai
}
const userSlice = créerSlice({
nom : 'utilisateur',
Etat initial,
réducteurs : {
getPassword : (état, action) => {
const mot de passe = action.payload
console.log(mot de passe)
}
},
extraRéducteurs : {
[loginUser.ending] : (état) => {
state.isLoading = faux
},
[loginUser.fulfilled] : (état, action) => {
state.isLoading = faux
état.utilisateur = action.payload.data
},
[loginUser.rejected] : (état) => {
state.isLoading = faux
},
[signupUser.ending] : (état) => {
state.isLoading = faux
},
[signupUser.fulfilled] : (état, action) => {
state.isLoading = faux
état.utilisateur = action.payload.data
},
[signupUser.rejected] : (état) => {
state.isLoading = faux
},
}
})
exporter const { getPassword } = userSlice.actions
exporter userSlice.reducer;</pre></p>