cari

Rumah  >  Soal Jawab  >  teks badan

Tajuk ditulis semula kepada: Laluan yang dilindungi dalam React Route v6 tidak dikemas kini apabila pengguna log masuk

<p>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). </p> <p>Terima kasih banyak atas bantuan anda. Terima kasih. </p> <p>Berikut ialah kod saya: </p> <p>Login.js -- Fail ini bertanggungjawab untuk menerima bukti kelayakan, menghantar tindakan menggunakan useDispatch dan mengemas kini keadaan menggunakan useDispatch. </p> <pre class="brush:php;toolbar:false;">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 ( <div> <masukan type="teks" value={email} onChange={(e) => setEmail(e.target.value)} /> <masukan type="kata laluan" nilai={kata laluan} onChange={(e) => setPassword(e.target.value)} /> <jenis butang="serahkan" penghantaran(loginUser({e-mel, kata laluan})) navigasi('/resipi') }}>serahkan</button> </div> ) }</pre> <p>ProtectedRoute.js -- Komponen ini memastikan bahawa jika pengguna tidak disahkan, dia tidak akan dapat log masuk</p> <pre class="brush:php;toolbar:false;">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 ? <Outlet /> ) }</pre> <p>app.js -- Komponen ini mengandungi semua laluan, termasuk laluan yang dilindungi. </p> <pre class="brush:php;toolbar:false;">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 ( <div> <Penghala Penyemak Imbas> <Laluan> <Laluan laluan="/login" elemen indeks={<Log masuk />} /> <Laluan laluan="/"elemen={<Navigasi ganti ke="/log masuk" <Elemen laluan={<ProtectedRoute />}> <Elemen laluan={<Resipi/>} laluan="/resipi" </Laluan> </Laluan> </BrowserRouter> </div> ); }; eksport Apl lalai;</pre> <p>userSlice.js -- 由于我使用redux toolkit,因此我有不同功能的slices。这里有reducers,其中有用户物用户犟 <pre class="brush:php;toolbar:false;">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;</pre></p>
P粉297434909P粉297434909484 hari yang lalu479

membalas semua(1)saya akan balas

  • P粉043432210

    P粉0434322102023-08-30 12:24:05

    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}
    

    Lihat Mengendalikan Keputusan Thunk untuk butiran lanjut.

    Anda juga boleh memudahkan ProtectedRoutelogik 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 ? <Outlet /> : <Navigate to="/login" replace />;
    }

    balas
    0
  • Batalbalas