标题重写为:用户登录时,React Route v6中的受保护路由未更新
P粉297434909
P粉297434909 2023-08-29 15:00:09
[React讨论组]

我正在尝试登录用户。我有一个登录组件,它接收凭据,然后我使用redux toolkit来存储状态,并且验证和所有操作都在userSlice中完成。我有一个受保护的路由,应该检查用户是否已登录,如果用户未登录,则不应导航到我拥有的食谱页面。当我尝试使用useSelecter hook从受保护的路由组件访问用户时,它在第一次渲染时返回空,但在第二次渲染时确实返回用户,但登录仍然失败。在redux dev tools中,状态被更新得很好。是否有一种方法可以在受保护的路由组件的第一次渲染中获取用户对象?(正如您所看到的,我正在使用useEffect hook,并且有依赖数组)。

非常感谢您的帮助。 谢谢。

下面是我的代码:

Login.js -- 这个文件负责接收凭据,然后使用useDispatch分派一个动作并使用useDispatch更新状态。

import React, { useState } from 'react';
import { loginUser } from '../../features/users/userSlice';
import { useSelector, useDispatch } from 'react-redux'
import { useNavigate } from 'react-router-dom';

export default function Login() {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const  user  = useSelector(state => state.user.user)
  const dispatch = useDispatch()
  const navigate = useNavigate()


  return (
    <div>
        <input
        type="text"
        value={email}
        onChange={(e) => setEmail(e.target.value)}
      />
      <input
        type="password"
        value={password}
        onChange={(e) => setPassword(e.target.value)}
      />
      <button type="submit" onClick={() => {
        dispatch(loginUser({email, password}))
        navigate('/recipes')
      }}>submit</button>
    </div>
  )
}

ProtectedRoute.js -- 此组件确保如果用户未经身份验证,他将无法登录

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

export default function ProtectedRoute({ children }) {
  const [ activeUser, setActiveUser ] = useState(false)
  const user = useSelector((state) => state.user);
  useEffect(() => {
    if (!user.isLoading) {
      user.success ? setActiveUser(true) : setActiveUser(false)
      console.log('active user: ' + activeUser)
    }
  }, [user])

  return (
    activeUser ? <Outlet /> : <Navigate to="/login"/>
  )
}

app.js -- 此组件包含所有路由,包括受保护的路由。

import React from "react";
import Recipes from "./components/recipes/recipes";
import Login from "./components/users/Login";
import { BrowserRouter, Routes, Route, Navigate } from "react-router-dom";
import ProtectedRoute from "./utils.js/ProtectedRoute";

const App = () => {
  return (
    <div>
      <BrowserRouter>
        <Routes>
          <Route path="/login" index element={<Login />} />
          <Route path="/" element={<Navigate replace to="/login" />}/>
          <Route element={<ProtectedRoute />}>
            <Route element={<Recipes/>} path="/recipes" />
          </Route>
        </Routes>
      </BrowserRouter>
    </div>
  );
};

export default App;

userSlice.js -- 由于我使用redux toolkit,因此我有不同功能的slices。这里有reducers,其中有用户状态。

import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
import axios from "axios";

const loginUrl = 'http://localhost:5000/api/login';
const signupUrl = 'http://localhost:5000/api/signup';

export const loginUser = createAsyncThunk('user/loginUser', async (data) => {
    const response = await axios.post(loginUrl, data);
    return response;
})

export const signupUser = createAsyncThunk('user/signupUser', async (data) => {
    const response = await axios.post(signupUrl, data);
    return response;
})

const initialState = {
    user: {},
    isLoading: true
}

const userSlice = createSlice({
    name: 'user',
    initialState,
    reducers: {
        getPassword: (state, action) => {
            const password = action.payload
            console.log(password)
        }
    },
    extraReducers: {
        [loginUser.pending]: (state) => {
            state.isLoading = false
        },
        [loginUser.fulfilled]: (state, action) => {
            state.isLoading = false
            state.user = action.payload.data
        },
        [loginUser.rejected]: (state) => {
            state.isLoading = false
        },
        [signupUser.pending]: (state) => {
            state.isLoading = false
        },
        [signupUser.fulfilled]: (state, action) => {
            state.isLoading = false
            state.user = action.payload.data
        },
        [signupUser.rejected]: (state) => {
            state.isLoading = false
        },
    }
})

export const { getPassword } = userSlice.actions
export default userSlice.reducer;

P粉297434909
P粉297434909

全部回复(0)
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号