我有以下的身份验证上下文提供者。在用户成功认证后,我设置了一些令牌值
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;