検索

ホームページ  >  に質問  >  本文

タイトルが次のように書き換えられました: React Route v6 の保護されたルートがユーザーのログイン時に更新されない

<p>ユーザーにログインしようとしています。認証情報を受け取るログインコンポーネントがあり、redux ツールキットを使用して状態と検証を保存し、すべてが userSlice で行われます。ユーザーがログインしているかどうかを確認し、ユーザーがログインしていない場合はレシピページに移動しないようにする保護されたルートがあります。 useSelecter フックを使用して保護されたルーティング コンポーネントからユーザーにアクセスしようとすると、最初のレンダリングでは null が返されますが、2 番目のレンダリングではユーザーが返されますが、ログインは依然として失敗します。 Redux 開発ツールでは、ステータスが適切に更新されます。保護されたルーティング コンポーネントの最初のレンダリングでユーザー オブジェクトを取得する方法はありますか? (ご覧のとおり、useEffect フックを使用しており、依存関係配列があります)。 </p> <p>ご協力いただき誠にありがとうございます。 ありがとう。 </p> <p>これが私のコードです: </p> <p>Login.js -- このファイルは、資格情報を受信し、useDispatch を使用してアクションをディスパッチし、useDispatch を使用して状態を更新する役割を果たします。 </p> <pre class="brush:php;toolbar:false;">import React, { useState } from 'react'; import {loginUser} から '../../features/users/userSlice'; import { useSelector, useDispatch } から 'react-redux' import { useNavigate } から 'react-router-dom'; デフォルト関数 Login() をエクスポート { const [電子メール, setEmail] = useState(""); const [パスワード, setPassword] = useState(""); const user = useSelector(state => state.user.user) const ディスパッチ = useDispatch() const navigate = useNavigate() 戻る ( <div> <入力 type="テキスト" 値={電子メール} onChange={(e) => setEmail(e.target.value)} /> <入力 タイプ=「パスワード」 値={パスワード} onChange={(e) => setPassword(e.target.value)} /> <ボタンの種類="送信" onClick={() => { dispatch(loginUser({メールアドレス, パスワード})) ナビゲート('/レシピ') }}>送信</ボタン> </div> ) }</pre> <p>ProtectedRoute.js -- このコンポーネントは、ユーザーが認証されていない場合にログインできないことを保証します</p> <pre class="brush:php;toolbar:false;">import React, { useState, useEffect } from "react"; import { ルート、ナビゲート、アウトレット } from "react-router-dom"; import { useSelector } から 'react-redux'; デフォルト関数のエクスポート 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('アクティブなユーザー: ' activeUser) } }, [ユーザー]) 戻る ( activeUser ? <Outlet /> : <Navigate to="/login"/> ) }</pre> <p>app.js -- このコンポーネントには、保護されたルートを含むすべてのルートが含まれます。 </p> <pre class="brush:php;toolbar:false;">React を "react" からインポートします; 「./components/recipes/recipes」からレシピをインポートします; 「./components/users/Login」からログインをインポートします; import { BrowserRouter, Routes, Route, Navigate } from "react-router-dom"; 「./utils.js/ProtectedRoute」から ProtectedRoute をインポートします。 const App = () => { 戻る ( <div> <ブラウザルーター> <ルート> <ルートパス="/login"インデックス要素={<Login />} /> <ルートパス="/" element={<Navigate replace to="/login" />}/> <ルート要素={<ProtectedRoute />}> <ルート要素={<レシピ/>} パス="/レシピ" /> </ルート> </ルート> </ブラウザルーター> </div> ); }; デフォルトのアプリをエクスポート;</pre> <p>userSlice.js -- redux ツールキットを使用しているため、さまざまな機能を持つスライスがあります。ここにはユーザーステータスを持つリデューサーがあります。 </p> <pre class="brush:php;toolbar:false;">import { createSlice, createAsyncThunk } from "@reduxjs/toolkit"; "axios" から axios をインポートします。 const loginUrl = 'http://localhost:5000/api/login'; constsignupUrl = 'http://localhost:5000/api/signup'; import const loginUser = createAsyncThunk('user/loginUser', async (data) => { const 応答 = await axios.post(loginUrl, data); 応答を返します。 }) import constsignupUser = createAsyncThunk('user/signupUser', async (data) => { const 応答 = await axios.post(signupUrl, data); 応答を返します。 }) const 初期状態 = { ユーザー: {}、 isLoading: true } const userSlice = createSlice({ 名前: 'ユーザー'、 初期状態、 レデューサ: { getPassword: (状態、アクション) => { const パスワード = アクション.ペイロード console.log(パスワード) } }、 extraReducers: { [loginUser.pending]: (状態) => { state.isLoading = false }、 [loginUser.fulfilled]: (状態、アクション) => { state.isLoading = false state.user = アクション.ペイロード.データ }、 [loginUser.rejected]: (状態) => { state.isLoading = false }、 [signupUser.pending]: (状態) => { state.isLoading = false }、 [signupUser.fulfilled]: (状態、アクション) => { state.isLoading = false state.user = アクション.ペイロード.データ }、 [signupUser.rejected]: (状態) => { state.isLoading = false }、 } }) エクスポート const { getPassword } = userSlice.actions デフォルトの userSlice.reducer;</pre></p> をエクスポートします。
P粉297434909P粉297434909484日前480

全員に返信(1)返信します

  • P粉043432210

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

    問題は、ログイン ハンドラーが 2 つのアクションを同時に発行することです。

    リーリー

    ユーザーが認証する前に、保護されたルートに移動します。

    この問題を解決するには、ログイン ハンドラーは認証が成功するまで待機してから、必要なルートにリダイレクトする必要があります。

    リーリー

    詳細については、サンク結果の処理を参照してください。

    ProtectedRoute ロジックを簡素化することもできます。追加の再レンダリングは必要なく、レンダリングする正しい出力を取得するだけです。すべてのルート ガード ステートは、選択した redux ステートから派生できます。

    リーリー

    返事
    0
  • キャンセル返事