タイトルが次のように書き換えられました: React Route v6 の保護されたルートがユーザーのログイン時に更新されない
P粉297434909
2023-08-29 15:00:09
<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> をエクスポートします。
問題は、ログイン ハンドラーが 2 つのアクションを同時に発行することです。
リーリーユーザーが認証する前に、保護されたルートに移動します。
この問題を解決するには、ログイン ハンドラーは認証が成功するまで待機してから、必要なルートにリダイレクトする必要があります。
リーリー詳細については、サンク結果の処理を参照してください。
ProtectedRoute
ロジックを簡素化することもできます。追加の再レンダリングは必要なく、レンダリングする正しい出力を取得するだけです。すべてのルート ガード ステートは、選択した redux ステートから派生できます。