我是一名初学者开发人员,试图创建一个 MERN stack Facebook 克隆,如果用户未登录,他们将被带到带有注册/登录表单的登陆页面。如果用户登录,他们将被带到主应用程序,带有“/”、“/messages”、“/profile”和“/users/:userID”路由。
最初我将它们全部放在
app.js
中,并使用返回布尔值的 isLoggedIn
函数。我尝试执行以下操作,但现在它找不到除“/”之外的任何仅登录的路由。在“/”和“/welcome”上一切正常,并且重定向在 app.js
中是双向的。
提前致谢!
Index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './components/app/App';
import { BrowserRouter } from 'react-router-dom';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<BrowserRouter>
<React.StrictMode>
<App />
</React.StrictMode>
</BrowserRouter>
);
App.js
import './App.css';
import React, { useState } from 'react';
import Feed from '../feed/Feed';
import HomePage from '../../pages/HomePage';
import {
useNavigate,
Routes,
Route,
Navigate,
} from "react-router-dom";
import { isLoggedIn } from '../../utilities/LoggedInCheck';
import LandingPage from '../../pages/LandingPage';
import AuthenticatedRoutes from './AuthenticatedRoutes';
const App = () => {
const navigate = useNavigate();
return (
<Routes>
{/* ====== AUTHENTICATION ONLY - Search, Messages, Friends, Notifications : ======== */}
<Route path='/' element={ isLoggedIn() ?
<AuthenticatedRoutes navigate={navigate}/> : <Navigate to='/welcome'/>}/>
{/* ====== NO AUTHENTICATION - Sign Up or Login: ======== */}
<Route path='/welcome' element={ !isLoggedIn() ?
<LandingPage navigate={navigate}/> : <Navigate to='/'/>}/>
</Routes>
);
}
export default App;
AuthenticatedRoutes.js--我对每个经过身份验证的页面使用相同的布局,因此请跳到路线部分的“MAIN DIV”位置。
import React, { useState, useEffect } from 'react';
import {
Routes,
Route,
} from "react-router-dom";
import { useSessionTimeOutCheck } from '../../utilities/LoggedInCheck';
import { isLoggedIn } from '../../utilities/LoggedInCheck';
import LoginPopup from '../auth/LoginPopup';
import { findUser } from '../../api_calls/usersAPI';
import HomePage from '../../pages/HomePage';
import ProfilePage from '../../pages/ProfilePage';
import OwnProfilePage from '../../pages/OwnProfilePage';
import MessengerPage from '../../pages/MessengerPage';
import Profile from '../profilepage/Profile';
import OwnProfile from '../profilepage/OwnProfile';
import Navbar from '../navbar/Navbar';
import getSessionUserID from '../../utilities/GetSessionUserID';
import Feed from '../feed/Feed';
const AuthenticatedRoutes = ({navigate}) => {
const [token, setToken] = useState(window.localStorage.getItem('token'));
const sessionUserID = getSessionUserID(token);
const [sessionUser, setSessionUser] = useState(null);
// ===== LOGIN POPUP & TIMEOUT CHECKER: COPY TO EVERY AUTHENTICATED PAGE: ==========
const showLoginPopup = !useSessionTimeOutCheck(); // checks every 5 seconds if token is valid and changes true/false
// on component mount: get sessionUserInfo
// TODO test:copy to every page, so that it reloads on every new page visit?
useEffect(() => {
if (token && sessionUserID) {
findUser(token, sessionUserID)
.then(userData => {
window.localStorage.setItem("token", userData.token)
setToken(window.localStorage.getItem("token"))
setSessionUser(userData.user);
console.log(userData.user);
})
}
},[])
// =========== JSX FOR COMPONENT ===================================
return (
<div className='h-screen w-screen bg-#bgGrey dark:bg-gray-900 flex flex-col'>
{/* LOGGED OUT POPUP */}
{showLoginPopup &&
<div className='z-40 absolute h-full w-full'>
<LoginPopup navigate={navigate} />
</div>
}
{/* NAV BAR */}
<div className='z-30'>
<Navbar navigate={navigate} token={token} setToken={setToken}
sessionUserID={sessionUserID} sessionUser={sessionUser} setSessionUser={sessionUser}/>
</div>
{/* MAIN PAGE */}
<div className='w-screen h-screen flex flex-row '>
{/* MAIN DIV */}
<div className='w-full h-full'>
<Routes>
{/* ------ FEED ------ */}
<Route path='/' element={
<Feed navigate={navigate} token={token} setToken={setToken}
sessionUserID={sessionUserID} sessionUser={sessionUser} setSessionUser={sessionUser}/>} />
{/* ------ PROFILE PAGE ------ */}
<Route path="/users/:userID/" element={
<Profile navigate={navigate} token={token} setToken={setToken}
sessionUserID={sessionUserID} sessionUser={sessionUser} setSessionUser={sessionUser}/>}/>
{/* ------ SESSION USER'S PROFILE PAGE ------ */}
<Route path='/profile' element={
<OwnProfile navigate={navigate} token={token} setToken={setToken}
sessionUserID={sessionUserID} sessionUser={sessionUser} setSessionUser={sessionUser}/>}/>
{/* ------ MESSAGES ------ */}
{/* <Route path='/messages' element={
<MessengerPage navigate={navigate} token={token} setToken={setToken}
sessionUserID={sessionUserID} sessionUser={sessionUser} setSessionUser={sessionUser}/>}/> */}
</Routes>
</div>
{/* MESSENGER DIV - Online friends */}
<div className='flex flex-row items-center justify-between h-full sm:w-[28rem] md:w-[30.5rem] lg:w-[34.5rem] px-4
border-l-2'>
MESSENGER
</div>
</div>
</div>
);
}
export default AuthenticatedRoutes;
要解决此问题,请在 App.js 和 AuthenticatedRoutes.js 中进行更改以正确处理路由和身份验证。
在 App.js 中:
import React from 'react';
import { Routes, Route, Navigate } from "react-router-dom";
import LandingPage from '../../pages/LandingPage';
import AuthenticatedRoutes from './AuthenticatedRoutes';
import { isLoggedIn } from '../../utilities/LoggedInCheck';
const App = () => {
return (
<Routes>
// Here the <AuthenticatedRoutes /> only rendered if the user is logged in, otherwise, it will redirects to the landing page.
<Route
path="/"
element={isLoggedIn() ? <AuthenticatedRoutes /> : <LandingPage />}
/>
<Route path="/welcome" element={<LandingPage />} />
</Routes>
);
};
export default App;
以及在 AuthenticatedRoutes.js 中:
import React, { useEffect, useState } from 'react';
import { Routes, Route } from "react-router-dom";
import { isLoggedIn } from '../../utilities/LoggedInCheck';
import LandingPage from '../../pages/LandingPage';
import Feed from '../feed/Feed';
import Profile from '../profilepage/Profile';
import OwnProfile from '../profilepage/OwnProfile';
const AuthenticatedRoutes = () => {
const [isLoggedInState, setIsLoggedIn] = useState(isLoggedIn());
useEffect(() => {
setIsLoggedIn(isLoggedIn());
}, []);
if (!isLoggedInState) {
return <LandingPage />;
}
return (
<Routes>
<Route path="/" element={<Feed />} />
<Route path="/profile" element={<OwnProfile />} />
<Route path="/users/:userID" element={<Profile />} />
{/* other routes....*/}
</Routes>
);
};
export default AuthenticatedRoutes;