Tajuk ditulis semula kepada: Laluan yang dilindungi dalam React Route v6 tidak dikemas kini apabila pengguna log masuk
P粉297434909
P粉297434909 2023-08-29 15:00:09
0
1
360

Saya cuba melog masuk pengguna. Saya mempunyai komponen log masuk yang menerima kelayakan dan kemudian saya menggunakan kit alat redux untuk menyimpan keadaan dan pengesahan dan semuanya dilakukan dalam userSlice. Saya mempunyai laluan yang dilindungi yang harus menyemak sama ada pengguna telah log masuk dan jika pengguna tidak log masuk ia tidak sepatutnya menavigasi ke halaman resipi yang saya ada. Apabila saya cuba mengakses pengguna daripada komponen penghalaan yang dilindungi menggunakan cangkuk useSelecter, ia mengembalikan null pada pemaparan pertama, tetapi mengembalikan pengguna pada pemaparan kedua, tetapi log masuk masih gagal. Dalam alat redux dev, status dikemas kini dengan baik. Adakah terdapat cara untuk mendapatkan objek pengguna pada paparan pertama komponen penghalaan yang dilindungi? (Seperti yang anda lihat saya menggunakan cangkuk useEffect dan mempunyai tatasusunan dependensi).

Terima kasih banyak atas bantuan anda. Terima kasih.

Berikut ialah kod saya:

Login.js -- Fail ini bertanggungjawab untuk menerima bukti kelayakan, menghantar tindakan menggunakan useDispatch dan mengemas kini keadaan menggunakan useDispatch.

import React, { useState } daripada 'react'; import { loginUser } daripada '../../features/users/userSlice'; import { useSelector, useDispatch } daripada 'react-redux' import { useNavigate } daripada 'react-router-dom'; eksport fungsi lalai Log masuk() { const [e-mel, setEmail] = useState(""); const [kata laluan, setPassword] = useState(""); const user = useSelector(state => state.user.user) const dispatch = useDispatch() const navigate = useNavigate() kembali ( 
setEmail(e.target.value)} /> setPassword(e.target.value)} /> serahkan
) }

ProtectedRoute.js -- Komponen ini memastikan bahawa jika pengguna tidak disahkan, dia tidak akan dapat log masuk

import React, { useState, useEffect } daripada "react"; import { Route, Navigate, Outlet } dari "react-router-dom"; import { useSelector } daripada 'react-redux'; eksport fungsi lalai ProtectedRoute({kanak-kanak}) { const [ activeUser, setActiveUser ] = useState(false) pengguna const = useSelector((state) => state.user); useEffect(() => { jika (!user.isLoading) { user.success ? setActiveUser(true) : setActiveUser(false) console.log('pengguna aktif: ' + activeUser) } }, [pengguna]) kembali ( activeUser ?  ) }

app.js -- Komponen ini mengandungi semua laluan, termasuk laluan yang dilindungi.

import React daripada "react"; import Resipi daripada "./komponen/resipi/resipi"; import Log Masuk daripada "./components/users/Login"; import { BrowserRouter, Routes, Route, Navigate } daripada "react-router-dom"; import ProtectedRoute daripada "./utils.js/ProtectedRoute"; const App = () => kembali ( 
} /> }> } laluan="/resipi"
); }; eksport Apl lalai;

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

import { createSlice, createAsyncThunk } daripada "@reduxjs/toolkit"; import axios daripada "axios"; const loginUrl = 'http://localhost:5000/api/login'; const signupUrl = 'http://localhost:5000/api/signup'; eksport const loginUser = createAsyncThunk('user/loginUser', async (data) => { respons const = tunggu axios.post(loginUrl, data); balasan balas; }) eksport const signupUser = createAsyncThunk('user/signupUser', async (data) => { respons const = tunggu axios.post(signupUrl, data); balasan balas; }) const initialState = { pengguna: {}, isLoading: benar } const userSlice = createSlice({ nama: 'pengguna', keadaan awal, pengurang: { getPassword: (keadaan, tindakan) => { kata laluan const = action.payload console.log(kata laluan) } }, extraReducers: { [loginUser.pending]: (nyatakan) => { state.isLoading = palsu }, [loginUser.fulfilled]: (nyatakan, tindakan) => { state.isLoading = palsu state.user = action.payload.data }, [loginUser.rejected]: (nyatakan) => { state.isLoading = palsu }, [signupUser.pending]: (nyatakan) => { state.isLoading = palsu }, [signupUser.fulfilled]: (nyatakan, tindakan) => { state.isLoading = palsu state.user = action.payload.data }, [signupUser.rejected]: (nyatakan) => { state.isLoading = palsu }, } }) export const { getPassword } = userSlice.actions eksport lalai userSlice.reducer;

P粉297434909
P粉297434909

membalas semua (1)
P粉043432210

Masalahnya ialah pengendali log masuk mengeluarkan dua tindakan pada masa yang sama.

onClick={() => { dispatch(loginUser({ email, password })); // <-- 登录用户 navigate('/recipes'); // <-- 立即导航 }}

Navigasi ke laluan yang dilindungi sebelum pengguna membuat pengesahan.

Untuk menyelesaikan masalah ini, pengendali log masuk harus menunggu pengesahan yang berjaya dan kemudian mengubah hala ke laluan yang diperlukan.

const loginHandler = async () => { try { const response = await dispatch(loginUser({ email, password })).unwrap(); if (/* 检查响应条件 */) { navigate("/recipes", { replace: true }); } } catch (error) { // 处理任何错误或被拒绝的 Promise } }; ... onClick={loginHandler}

LihatMengendalikan Keputusan Thunkuntuk butiran lanjut.

Anda juga boleh memudahkanProtectedRoutelogik anda supaya tiada pemaparan semula tambahan diperlukan, cuma dapatkan output yang betul untuk dipaparkan. Semua keadaan perlindungan laluan boleh diperoleh daripada keadaan redux terpilih.

export default function ProtectedRoute() { const user = useSelector((state) => state.user); if (user.isLoading) { return null; // 或者加载指示器/旋转器等 } return user.success ?  : ; }
    Muat turun terkini
    Lagi>
    kesan web
    Kod sumber laman web
    Bahan laman web
    Templat hujung hadapan
    Tentang kita Penafian Sitemap
    Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!