Maison  >  Questions et réponses  >  le corps du texte

useState dans ReactJS ne fonctionne pas lors de la mise à jour de l'objet

J'ai le fournisseur de contexte d'authentification suivant. Une fois l'authentification réussie de l'utilisateur, je définis quelques valeurs de jeton

import axios from "axios";
import { createContext, useContext, useState } from "react";
import Constants from "../common/Constants";
import Payload from "../classes/Payload";

const AuthenticationContext = createContext({
    loggedUserToken: {},
    session: {}
});

export const useAuthenticationStatus = () => useContext(AuthenticationContext);

const AuthenticationContextProvider = ({children}) => {

    const [loggedUserToken, setLoggedUserToken]     = useState({});
    const [session, setSession]                     = useState({});


    const authenticateUser = async (loginEndpoint, email, userPassword) => {         

        let result                                  = {};
        let statusCode                              = -1;
        let statusText                              = '';
        let message                                 = '';
        let session                                 = '';
        let postData                                = {username: email, password: userPassword};

        await axios.post(loginEndpoint, postData, {headers: headerData})
                .then( data => {

                    statusCode                      = data.data.code;
                    statusText                      = data.data.statusText;
                    session                         = data.data.session;
                    message                         = data.data.message;

                    if (statusCode === 200) {                

                        let challengeName           = message.challengeName;
                        let payloadData             = '';
                        
                        if (session !== null && message.challenge !== null) {

                            let userEmail           = message.userEmail;
                            setSession({'sD': session, 'sE': userEmail });
                            
                            if (challengeName === Constants.COGNITO_CHALLENGE_NEW_PASSWORD_REQUIRED ) {
                                statusText          = Constants.AUTHENTICATION_SET_NEW_PASSWSORD;
                                payloadData         = challengeName;
                            }

                            result = { 's': true, 'sT': statusText, 'p': payloadData};

                        } else {
                            statusText              = Constants.AUTHENTICATION_LOGIN_SUCCESSFUL;
                            payloadData             = message;

                            let userpayloadData      = new Payload(payloadData);

                            //set use state for user token - ERROR IN HERE
                            //loggedUserToken IS NOT SET HERE
                            setLoggedUserToken(loggedUserToken => userpayloadData);

                            result = { 's': true, 'sT': statusText, 'p': payloadData};

                        }                        

                    }

                }).catch( error => {
                    
                    result = { 's': false, 'sT': Constants.COMMON_ERROR_MESSAGE, 'p': ''};

                });

        return result;  
    }

    

    return (
        <AuthenticationContext.Provider
            value={{loggedUserToken, authenticateUser, session, setPermanentPassword}}>
            {children}
        </AuthenticationContext.Provider>
    )
};

export default AuthenticationContextProvider;

J'ai utilisé la valeur "loggedUserToken" dans la vue d'accueil pour vérifier si elle est disponible.

import { useEffect } from "react";
import { useAuthenticationStatus } from "../../services/AuthenticateContextProvider";

function HomeView() {

    const {loggedUserToken} = useAuthenticationStatus();
    
    //empty object output
    console.log(loggedUserToken);

    useEffect( () => {
        //empty object output
        console.log(loggedUserToken);
    })

    return (

        
        <div className="col-12">
            
            <div className="row mt-2">
                <div className="col-12">

                </div>
            </div>

            <div className="row mt-5 incident-list-map">

                <div className="col-md-4">

                    <h2>List</h2>
                    
                    <div></div>

                </div>

                <div className="col-md-8">
                    <div id="map" className="map">
                        
                    </div>

                </div>

            </div>

        </div>

    );
}

export default HomeView;

"loggedUserToken" est toujours vide même si vous le définissez dans le fournisseur d'authentification (même si vous l'imprimez sur la console immédiatement après "setLoggedUserToken" sur le fournisseur d'authentification). "setSession" est défini correctement, la valeur est lue dans une autre vue.

Je ne suis pas sûr de ce qui ne va pas ici

Mise à jour : voici comment j'utilise le fournisseur d'authentification. "Outlet" remplace différentes vues dans MainLayout.

import { Outlet } from "react-router-dom";
import MainHeader from "../common/MainHeader";
import MainFooter from "../common/MainFooter";
import AuthenticationContextProvider from "../../services/AuthenticateContextProvider";

function MainLayout() {

    return(

        <div className="main-layout">
            <AuthenticationContextProvider>
                <header>
                    <nav className="navbar navbar-expand-md fixed-top header-area">
                        <MainHeader></MainHeader>
                    </nav>
                </header>
                
                <main className="flex-shrink-0 main-area">
                    <div className="container-fluid">
                        <div className="main-content">
                            
                                <Outlet />
                            
                        </div>
                        
                    </div>
                </main>

                <footer className="footer mt-auto py-3 footer-content">
                    <div className="container-fluid">
                        <MainFooter></MainFooter>
                    </div>
                </footer>
            </AuthenticationContextProvider>
        </div>

    );

}

export default MainLayout;

P粉986028039P粉986028039365 Il y a quelques jours605

répondre à tous(1)je répondrai

  • P粉283559033

    P粉2835590332023-09-22 11:31:13

    J'ai trouvé la solution. L'erreur ci-dessus est causée par la mise en page que j'utilise. J'utilise une mise en page dans les vues d'authentification (comme la connexion, l'inscription, etc.) et une autre mise en page dans d'autres vues (accueil, contactez-nous, etc.).

    Je les ai encapsulés individuellement dans des fournisseurs de contexte d'authentification. Comme indiqué ci-dessous :

    import { Outlet } from "react-router-dom";
    import MainHeader from "../common/MainHeader";
    import MainFooter from "../common/MainFooter";
    import AuthenticationContextProvider from "../../services/AuthenticateContextProvider";
    
    function MainLayout() {
    
        return(
    
            <div className="main-layout">
                <AuthenticationContextProvider>
                    <header>
                        <nav className="navbar navbar-expand-md fixed-top header-area">
                            <MainHeader></MainHeader>
                        </nav>
                    </header>
                    
                    <main className="flex-shrink-0 main-area">
                        <div className="container-fluid">
                            <div className="main-content">
                                
                                    <Outlet />
                                
                            </div>
                            
                        </div>
                    </main>
    
                    <footer className="footer mt-auto py-3 footer-content">
                        <div className="container-fluid">
                            <MainFooter></MainFooter>
                        </div>
                    </footer>
                </AuthenticationContextProvider>
            </div>
    
        );
    
    }
    
    export default MainLayout;

    import { Outlet } from "react-router-dom";
    import MainHeader from "../common/MainHeader";
    import MainFooter from "../common/MainFooter";
    import AuthenticationContextProvider from "../../services/AuthenticateContextProvider";
    
    function MainLayout() {
    
    
        return(
    
            <div className="main-layout">
                
                    <header>
                        <nav className="navbar navbar-expand-md fixed-top header-area">
                            <MainHeader></MainHeader>
                        </nav>
                    </header>
                    
                    <main className="flex-shrink-0 main-area">
                        <div className="container-fluid">
                            <div className="main-content">
                                
                                    <Outlet />
                                
                            </div>
                            
                        </div>
                    </main>
    
                    <footer className="footer mt-auto py-3 footer-content">
                        <div className="container-fluid">
                            <MainFooter></MainFooter>
                        </div>
                    </footer>
    
            </div>
    
        );
    
    }
    
    export default MainLayout;

    Mais lorsque j'ai déplacé le fournisseur de contexte d'authentification dans App.js, cela a fonctionné. D'après ce que j'ai compris, je pense que ce qui se passe, c'est que le fournisseur de contexte d'authentification est réinitialisé lorsqu'il passe de la présentation d'authentification à la présentation principale (dans la présentation principale, il s'agit d'un fournisseur de contexte distinct). Mais depuis que j'ai déplacé le fournisseur de contexte au niveau supérieur (App.js), il est désormais commun à toutes les mises en page.

    import 'bootstrap/dist/css/bootstrap.css';
    import 'bootstrap/dist/js/bootstrap.js';
    import './App.css';
    import { Route, Routes } from 'react-router-dom';
    import AuthenticationLayout from './components/layouts/AuthenticationLayout';
    import LoginView from './components/authentication/LoginView';
    import ForgotPasswordView from './components/authentication/ForgotPasswordView';
    import MainLayout from './components/layouts/MainLayout';
    import HomeView from './components/main/HomeView';
    import ConfirmEmailView from './components/authentication/ConfirmEmailView';
    import SetNewPassword from './components/authentication/SetNewPassword';
    import AuthenticationContextProvider from './services/AuthenticateContextProvider';
    
    function App() {
    
      return (
    
        <>
          <AuthenticationContextProvider>
            <Routes>
              <Route element={ <AuthenticationLayout /> }>
                <Route path='/' element={ <LoginView /> }></Route>
                <Route path='/login' element={ <LoginView /> }></Route>
                <Route path='/forgotpassword' element={ <ForgotPasswordView />}></Route>
                <Route path='/confirmemail'element={ <ConfirmEmailView /> }></Route>
                <Route path='/setnewpassword' element={ <SetNewPassword /> }></Route>
              </Route>
    
              <Route element={ <MainLayout /> }>
                <Route path='/home' element={ <HomeView /> }></Route>
              </Route>
    
            </Routes>
          </AuthenticationContextProvider>
        </>
    
      );
    
    }
    
    export default App;

    répondre
    0
  • Annulerrépondre