搜索

首页  >  问答  >  正文

ReactJS中的useState在更新对象时不起作用

我有以下的身份验证上下文提供者。在用户成功认证后,我设置了一些令牌值

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;

我在主页视图中使用了"loggedUserToken"值来检查它是否可用。

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"始终为空(即使您在身份验证提供者上的"setLoggedUserToken"之后立即将其打印到控制台)。"setSession"已正确设置,在另一个视图中读取该值。

我不确定这里出了什么问题

更新:以下是我如何使用身份验证提供者。"Outlet"替换了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粉986028039434 天前658

全部回复(1)我来回复

  • P粉283559033

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

    我已经找到了解决方法。上述错误是由我使用的布局引起的。我在身份验证视图(如登录、注册等)中使用一个布局,而在其他视图(主页、联系我们等)中使用另一个布局。

    我已经将它们分别封装到身份验证上下文提供程序中。如下所示:

    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;

    但是当我将身份验证上下文提供程序移动到App.js中时,它就可以工作了。在我理解的情况下,我认为发生的是当它从身份验证布局移动到主布局时,身份验证上下文提供程序被重置了(在主布局中它是一个单独的上下文提供程序)。但是由于我将上下文提供程序移动到了最顶层(App.js),它现在在所有布局中都是通用的。

    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;

    回复
    0
  • 取消回复