🎧

useNavigate + useLocationで遷移先に送付する値を管理する

2022/01/29に公開

こんにちは。WEBエンジニアのホリさんです。
今回が第1回目の記事です。

概要

useNavigateを使用して、画面遷移先に値を送り、useLocationを使って受け取る方法があります。

React Router v5 → v6にアップデートされ、useHistoryuseNavigateに変更になってから
値の送り方・受け取り方の情報がなかったため、記事にさせていただきました。

useNavigateの使い方 🎓

useNavigateは簡単にいうと、ページ遷移や遷移先に値を渡すことが可能になるAPIになります。

構文は以下になります。

navigate(to, { state={}, replace=false })

to → URL
state → 遷移先で使用する値
replace → trueの場合、指定されたURLページに置き換えるのと、
ブラウザの戻るボタンを使って以前のページに戻ることができないようにする。
(ただし何回も戻るボタンを押すと戻れる)falseとの違いは、遷移先でも以前のページに戻ることができる。

実は書き方自体はそんなに変わらないです

navigateの第一引数にURLとstateにハッシュの{ id: 1 }を設定します。もし値だけ設定したい場合は
{ state: 1 } でも可能です。

UserPage.tsx
import { VFC } from "react"
- import { useHistory } from "react-router-dom"
+ import { useNavigate } from "react-router-dom"

export const UserPage: VFC = memo(() => {
- const history = useHistory()
+ const navigate = useNavigate()
  
  const handleClick = () => {
- history.push('/dashboard', { state: { id: 1 }})
+ navigate("/dashboard", { state: { id: 1 } })
  }
  
  return (
    <button onClick={handleClick}></button>
  )
}

useLocationの使い方 🔨

useLocationは、現在のページのURLのpathやqueryなどの情報を取得できます。

以下は先ほどのページから遷移してきたファイルになります。

navigate("dashboard", { state: { id: 1 } }で値を設定したのを、useLocationで取得します。取得したあとは、useStateでselectIDを定義して、状態管理をします。
{selectID.id} で値を出力することができます。

補足

useState<{ id: number }>の <{ id: number }> で状態管理する型を決めています。
location.state as { id: number } の as { id: number } で値の型を決めます。
typeScriptを使用する場合は、stateにも型を定義する必要があります。

dashboard.tsx
import { memo, useState, VFC } from "react"
import { useLocation } from "react-router-dom"

export const Dashboard: VFC = memo(() => {
  const location = useLocation()
  const [selectId, setSelectId] 
  = useState<{ id: number }>(location.state as { id: number })
  
  return (
    <>
      <h1>ユーザーのダッシュボード</h1>
      {selectId.id}
    </>
  )
})

他の方法

個人的には遷移先に値を渡すとき、ページの意味を指している場合はURLから値を取得する方が良いと思っています。
例えば、ダッシュボードの詳細画面に遷移する際にURLは、dashboard/:idとすると何のページか分かりやすくなります。

まずURLにidを付与します

UserPage.tsx
・
・
(省略)
※idという変数がある想定
navigate(`/dashboard/${id}`)
・
・

ルーティングファイルに /dashboard/:id を定義します。:idがUserPage.tsxで設定したidに該当します。

Router.tsx
import { memo, VFC } from "react"
import { Route, Routes } from "react-router-dom"

export const UserRouter: VFC = memo(() => {
  const location = useLocation()

  return (
    <>
      <Routes>
        <Route path="/user" element={<UserPage />}
        <Route path="/dashboard/:id" element={<Dashboard />} />
      </Routes>
    </>
  )
})

useParams を使用します
動的なidなどのパラメータ値を扱うことができるAPIになります。

params.idと定義するとidが出力されます。

Dashboard.tsx
import { memo, VFC } from "react";
import { useParams } from "react-router-dom";

export const Dashboard: VFC = memo(() => {
const params = useParams();
  
  return (
    <>
      <h1>ユーザーのダッシュボード</h1>
      {params.id}
    </>
  );
});

まとめ

  • useNavigate + useLocation
  • useNavigate + useParams

のページ遷移先に値を渡す方法について解説しました。

一番安全な方法はページ遷移するときにAPIを叩いて、バックエンド側でidが存在するか確認して、レスポンスで返すことがセキュリティーや結合レベルでもエラー原因になりにくいと思います。
ただ、ページの切り替えでそこまでユーザ側に影響しない値であれば、紹介した方法で値を渡すのでもいいと思いました。

参考URL

https://reach.tech/router/api/useNavigate
https://dev-yakuza.posstree.com/react/create-react-app/react-router/

Discussion