我正在try 这样做,当用户单击某个链接(上传组件)时,它会将他们重定向到登录组件,并且不确定如何在React中完成此任务.100我知道我需要创建自己的受保护路由(可能),但我看到其他人正在访问useContext,我没有任何带有上下文的文件.我在react dom中使用版本6.我也在我的项目中使用React router和redux,所以我知道我需要以某种方式访问状态,只是不知道如何将我的 idea 围绕它,所以如果有人能提供帮助,我将不胜感激.用户通过JWT身份验证存储在本地存储器中.

应用程序.js:

import React, {useState, useEffect, useCallback} from 'react';
import {useDispatch, useSelector} from 'react-redux';
import {BrowserRouter as Router, Routes, Route} from 'react-router-dom'; //Switch was replaced by Routes in react-router-dom v6
import './App.css';
import Navbar from './components/Navbar';
import Footer from './components/Footer';
import Home from './components/pages/Home';
import Uploads from './components/pages/Uploads';
import Account from './components/pages/Account';
import Login from './components/pages/Login';
import LogOut from './components/Logout';
import Register from './components/pages/Register';
import Profile from './components/pages/Profile';
import EditProfile from './components/pages/EditProfile';
import BoardAdmin from './components/pages/BoardAdmin';
import BoardModerator from './components/pages/BoardModerator';
import BoardUser from './components/pages/BoardUser';
import {logout} from './slices/auth';
import EventBus from './common/EventBus';

const App = () => {
    const [showModeratorBoard, setShowModeratorBoard] = useState(false);
    const [showAdminBoard, setShowAdminBoard] = useState(false);
    const {user: currentUser} = useSelector((state) => state.auth);
    const dispatch = useDispatch();

    useEffect(() => {
        if (currentUser) {
            setShowModeratorBoard(currentUser.roles.includes('ROLE_MODERATOR'));
            setShowAdminBoard(currentUser.roles.includes('ROLE_ADMIN'));
        } else {
            setShowModeratorBoard(false);
            setShowAdminBoard(false);
        }
    }, [currentUser]);

    return (
        <>
            <Router>
                <Navbar />
                <Routes>
                    <Route path='/' element={<Home />} />
                    <Route path='/create/upload' element={<Uploads />} />
                    <Route path='/my-account' element={<Account />} />
                    <Route path='/login' element={<Login />} />
                    <Route path='/logout' element={<LogOut />} />
                    <Route path='/register' element={<Register />} />
                    <Route path='/profile' element={<Profile />} />
                    <Route path='/profile/edit' element={<EditProfile />} />
                    <Route path='/user' element={<BoardUser />} />
                    <Route path='/mod' element={<BoardModerator />} />
                    <Route path='/admin' element={<BoardAdmin />} />
                </Routes>
                <Footer />
            </Router>
        </>
    );
};

export default App;

啊.js:

import {createSlice, createAsyncThunk} from '@reduxjs/toolkit';
import {setMessage} from './messages';
import AuthService from '../services/auth.service';
const user = JSON.parse(localStorage.getItem('user'));
export const register = createAsyncThunk(
    'auth/register',
    async ({username, email, password}, thunkAPI) => {
        try {
            const response = await AuthService.register(username, email, password);
            thunkAPI.dispatch(setMessage(response.data.message));
            return response.data;
        } catch (error) {
            const message =
                (error.response &&
                    error.response.data &&
                    error.response.data.message) ||
                error.message ||
                error.toString();
            thunkAPI.dispatch(setMessage(message));
            return thunkAPI.rejectWithValue();
        }
    }
);
export const login = createAsyncThunk(
    'auth/login',
    async ({username, password}, thunkAPI) => {
        try {
            const data = await AuthService.login(username, password);
            return {user: data};
        } catch (error) {
            const message =
                (error.response &&
                    error.response.data &&
                    error.response.data.message) ||
                error.message ||
                error.toString();
            thunkAPI.dispatch(setMessage(message));
            return thunkAPI.rejectWithValue();
        }
    }
);
export const logout = createAsyncThunk('auth/logout', async () => {
    await AuthService.logout();
});
const initialState = user
    ? {isLoggedIn: true, user}
    : {isLoggedIn: false, user: null};
const authSlice = createSlice({
    name: 'auth',
    initialState,
    extraReducers: {
        [register.fulfilled]: (state, action) => {
            state.isLoggedIn = false;
        },
        [register.rejected]: (state, action) => {
            state.isLoggedIn = false;
        },
        [login.fulfilled]: (state, action) => {
            state.isLoggedIn = true;
            state.user = action.payload.user;
        },
        [login.rejected]: (state, action) => {
            state.isLoggedIn = false;
            state.user = null;
        },
        [logout.fulfilled]: (state, action) => {
            state.isLoggedIn = false;
            state.user = null;
        },
    },
});
const {reducer} = authSlice;
export default reducer;

在我的上传文件中添加if语句似乎是为了让登录用户可以访问文件中的h1元素,而不是未经身份验证的用户.所以它在一定程度上是有效的,只是没有重定向回登录.

上载jsx:

import React from 'react';
import {Link} from 'react-router-dom';
import {useSelector} from 'react-redux';
function Uploads() {
    const {user: currentUser} = useSelector((state) => state.auth);
    if (!currentUser) {
        return <Link to='/login' />;
    }
    return (
        <>
            <h1 className='page'>UPLOADS</h1>
        </>
    );
}

export default Uploads;

推荐答案

渲染Link不需要强制导航,使用Navigation组件.

例子:

import React, { useEffect } from 'react';
import { Navigate } from 'react-router-dom';
import { useSelector } from 'react-redux';

function Uploads() {
  const { user: currentUser } = useSelector((state) => state.auth);

  if (!currentUser) {
    return <Navigate to='/login' replace />;
  }
  return (
    <>
      <h1 className='page'>UPLOADS</h1>
    </>
  );
}

export default Uploads;

通常你会保护路由.如果你想这么做:

import { Navigate, Outlet } from 'react-router-dom';
import { useSelector } from 'react-redux';

const PrivateRoutes = () => {
  const { user: currentUser } = useSelector((state) => state.auth);
  return currentUser 
    ? <Outlet />
    : <Navigate to="/login" replace />;
}

...

<Routes>
  <Route path='/' element={<Home />} />
  <Route element={<PrivateRoutes />}>
    <Route path='/create/upload' element={<Uploads />} />
    ... any other protected routes ...
  </Route>
  ... other unprotected routes ...
</Routes>

Javascript相关问答推荐

为什么我无法使用useMemo()停止脚本渲染?

如何在非独立组件中使用独立组件?

通过实现regex逻辑自定义数据表搜索

使用print This时, map 容器已在LeafletJS中初始化

如何使用Echart 5.5.0创建箱形图

在贝塞尔曲线的直线上找不到交叉点:(使用@Pomax的bezier.js)

过滤对象数组并动态将属性放入新数组

Javascript,部分重排序数组

如何在mongoose中链接两个模型?

在grafana情节,避免冲突的情节和传说

如何将Openjphjs与next.js一起使用?

获取Uint8ClampedArray中像素数组的宽度/高度

Javascript json定制

我可以使用空手道用户界面来获取网页的当前滚动位置吗?

我在Django中的视图中遇到多值键错误

对网格项目进行垂直排序不起作用

如何在 Select 文本时停止Click事件?

如何利用CSS中的隐藏元素实现平滑扩展和防止网格行间隙

如何在Jest中模拟函数

在JavaScript中将Base64转换为JSON