ReactJS中的useState在更新物件時不起作用
P粉986028039
P粉986028039 2023-09-21 12:44:16
0
1
669

我有以下的身份驗證上下文提供者。在使用者成功認證後,我設定了一些令牌值

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(

        <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;
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板