如何为 React 应用程序创建仅登录的路由?

问题描述 投票:0回答:1

我是一名初学者开发人员,试图创建一个 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;

reactjs authentication routes react-router react-router-dom
1个回答
0
投票

要解决此问题,请在 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;
© www.soinside.com 2019 - 2024. All rights reserved.