【react-router-dom v6】認証前にアクセスしようとしていたURLに認証後に遷移するようにしたい

実現したいこと

ルーティング

下記のようなルーティングを持つアプリを作成しました

  • / : Dashboard コンポーネトを返す
  • /login : Login コンポーネントを返す
  • /sample: Sample コンポーネントを返す

仕様

アプリケーションの仕様は下記の通りです

  • 認証状態は簡易的に useState を使って管理しています
  • 最初はログインしておらず、Login コンポーネントからログインボタンをクリックすることでログインできます
  • ログインしていない状態で / or /sample にアクセスすると /login にリダイレクトします
  • ログインすると問答無用で Dashboard 画面に遷移します

実現したいこと

下記のようなことを実現したいです

/sample にアクセスしてから /login にリダイレクトしてログインを行った場合、
/dashboard ではなく、元々アクセスを試みていた /sample にリダイレクトされるようにしたい

発生している問題・分からないこと

元々アクセスを試みていた URL を保持しておく方法が分かりません

useState 及び useLocation を用いれば実現可能そうだと考えたのですが、
useLocation は Routes コンポーネントの配下でしか呼ぶことが出来ず、
手詰まりの状態になってしまっています

該当のソースコード

【Github】https://github.com/stc-h-mitsui/auth-redirect

TypeScript

1// main.tsx2 3import React from "react"4import ReactDOM from "react-dom/client"5import App from "./App.tsx"6import "./index.css"7 8ReactDOM.createRoot(document.getElementById("root")!).render(9 <React.StrictMode>10 <App />11 </React.StrictMode>12)13 14 15// App.tsx16import { useState } from "react"17import "./App.css"18import { RouterProvider, createBrowserRouter, redirect } from "react-router-dom"19import { Dashboard } from "./components/Dashboard"20import { Login } from "./components/Login"21import { Sample } from "./components/Sample"22 23function App() {24 const [isLogin, setIsLogin] = useState(false)25 const redirectIfNotLoggedIn = async () => {26 if (!isLogin) {27 throw redirect("/login")28 }29 return null30 }31 const redirectIfLoggedIn = async () => {32 if (isLogin) {33 throw redirect("/dashboard")34 }35 return null36 }37 38 const router = createBrowserRouter([39 {40 path: "/",41 loader: redirectIfNotLoggedIn,42 element: <Dashboard />,43 },44 {45 path: "/login",46 loader: redirectIfLoggedIn,47 element: <Login isLogin={isLogin} setIsLogin={setIsLogin} />,48 },49 {50 path: "/sample",51 loader: redirectIfNotLoggedIn,52 element: <Sample />,53 },54 ])55 56 return <RouterProvider router={router} />57}58 59export default App60 61 62// Login.tsx63import React, { useEffect } from "react"64import { useNavigate } from "react-router-dom"65 66export const Login: React.FC<{67 isLogin: boolean68 setIsLogin: React.Dispatch<boolean>69}> = ({ isLogin, setIsLogin }) => {70 const navigate = useNavigate()71 const handleClick = () => {72 setIsLogin(true)73 }74 useEffect(() => {75 navigate("/") // ここをログイン画面に遷移してくる前のURLにしたい76 }, [isLogin])77 return <button onClick={handleClick}>Login</button>78}79

試したこと・調べたこと

上記の詳細・結果

react-router-dom の公式ドキュメントを読み漁ったり、似たようなことをやっている記事がないか探したのですが、めぼしい情報を得られず、どのように解決したらよいか分かっておりません

補足

特になし

コメントを投稿

0 コメント