ReactJS中的useState在更新对象时不起作用
P粉986028039
P粉986028039 2023-09-21 12:44:16
0
1
459

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

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粉986028039
P粉986028039

全部回复(1)
P粉283559033

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

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

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

function MainLayout() {

    return(

        
); } 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(

        
); } 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 (

    <>
      
        
           }>
             }>
             }>
            }>
             }>
             }>
          

           }>
             }>
          

        
      
    

  );

}

export default App;
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!