useState in ReactJS not working when updating object
P粉986028039
P粉986028039 2023-09-21 12:44:16
0
1
581

I have the following authentication context provider. After the user successfully authenticates, I set some token values

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;

I used the "loggedUserToken" value in the home view to check if it is available.

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" is always empty even if you set it in the authentication provider (even if you print it to the console immediately after "setLoggedUserToken" on the authentication provider). "setSession" is set correctly, the value is read in another view.

I'm not sure what's wrong here

Update: Here is how I use the authentication provider. "Outlet" replaces different views in 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粉986028039
P粉986028039

reply all(1)
P粉283559033

I've found a solution. The above error is caused by the layout I'm using. I'm using one layout in authentication views (like login, registration, etc.) and another layout in other views (home, contact us, etc.).

I have encapsulated them separately into authentication context providers. As follows:

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;

But when I moved the authentication context provider into App.js, it worked. From what I understand, I think what is happening is that the authentication context provider is reset when it moves from the auth layout to the main layout (in the main layout it is a separate context provider). But since I moved the context provider to the top level (App.js), it is now common across all layouts.

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;
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!