我有以下的身份驗證上下文提供者。在使用者成功認證後,我設定了一些令牌值
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粉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;