React Router でプログラム的にナビゲーション時にデータを渡す方法

2024-06-08

React Router でプログラム的にナビゲーション時にデータを渡す方法

useNavigate フックと state プロパティ

useNavigate フックは、以下のコードのように使用できます。

import { useNavigate } from "react-router-dom";

const navigate = useNavigate();

const handleClick = () => {
  navigate("/some-route", { state: { data: "Hello, world!" } });
};

このコードでは、handleClick 関数は /some-route という URL にナビゲーションします。state プロパティには、data というキーで Hello, world! という値を持つオブジェクトが渡されます。

ナビゲーション先コンポーネントでは、useLocation フックを使用して、ナビゲーション時に渡されたデータを以下のコードのように受け取ることができます。

import { useLocation } from "react-router-dom";

const SomeRoute = () => {
  const location = useLocation();

  const data = location.state?.data;

  if (!data) {
    return <div>Data not found.</div>;
  }

  return <div>{data}</div>;
};

このコードでは、SomeRoute コンポーネントは useLocation フックを使用して location オブジェクトを取得します。location.state?.data でナビゲーション時に渡されたデータにアクセスできます。データが存在しない場合は、"Data not found" というメッセージを表示します。データが存在する場合は、そのデータを <div> タグ内に表示します。

React Router v6 では、useNavigate フックと state プロパティの使用方法が少し変更されました。v6 では、state プロパティを navigate 関数の第二引数として渡す必要があります。

import { useNavigate } from "react-router-dom";

const navigate = useNavigate();

const handleClick = () => {
  navigate("/some-route", { state: { data: "Hello, world!" } });
};

React Router v6 では、ナビゲーション先コンポーネントでデータを受け取る方法は変わりません。

import { useLocation } from "react-router-dom";

const SomeRoute = () => {
  const location = useLocation();

  const data = location.state?.data;

  if (!data) {
    return <div>Data not found.</div>;
  }

  return <div>{data}</div>;
};

React Router v6 と React Redux を組み合わせる場合は、useNavigate フックと state プロパティを使用して、Redux ストアからデータを渡すことができます。

import { useNavigate } from "react-router-dom";
import { useSelector } from "react-redux";

const navigate = useNavigate();
const data = useSelector((state) => state.data);

const handleClick = () => {
  navigate("/some-route", { state: { data: data } });
};

このコードでは、handleClick 関数は Redux ストアから data セクションを取得し、それを state プロパティに渡します。

React Router でプログラム的にナビゲーションを行う場合、useNavigate フックと state プロパティを使用して、ナビゲーション先コンポーネントにデータを渡すことができます。React Router v6 では、useNavigate フックと state プロパティの使用方法が少し変更されました。また、React Router v6 と React Redux を組み合わせる場合は、useNavigate フックと state プロパティを使用して、Redux ストアからデータを渡すことができます。




React Router でプログラム的にナビゲーション時にデータを渡す:サンプルコード

React Router v5

送信側コンポーネント (SendingComponent.js)

import React from 'react';
import { useNavigate } from 'react-router-dom';

const SendingComponent = () => {
  const navigate = useNavigate();
  const data = {
    id: 1,
    name: 'John Doe',
    email: '[email protected]',
  };

  const handleClick = () => {
    navigate('/profile', { state: { data } });
  };

  return (
    <div>
      <button onClick={handleClick}>プロフィールページへ移動</button>
    </div>
  );
};

export default SendingComponent;

受信側コンポーネント (Profile.js)

import React from 'react';
import { useLocation } from 'react-router-dom';

const Profile = () => {
  const location = useLocation();
  const data = location.state?.data;

  if (!data) {
    return <div>データが見つかりません。</div>;
  }

  return (
    <div>
      <h2>プロフィール</h2>
      <p>ID: {data.id}</p>
      <p>名前: {data.name}</p>
      <p>メールアドレス: {data.email}</p>
    </div>
  );
};

export default Profile;

React Router v6

送信側コンポーネント (SendingComponent.js)

import React from 'react';
import { useNavigate } from 'react-router-dom';

const SendingComponent = () => {
  const navigate = useNavigate();
  const data = {
    id: 1,
    name: 'John Doe',
    email: '[email protected]',
  };

  const handleClick = () => {
    navigate('/profile', { state: { data } });
  };

  return (
    <div>
      <button onClick={handleClick}>プロフィールページへ移動</button>
    </div>
  );
};

export default SendingComponent;

受信側コンポーネント (Profile.js)

import React from 'react';
import { useLocation } from 'react-router-dom';

const Profile = () => {
  const location = useLocation();
  const data = location.state?.data;

  if (!data) {
    return <div>データが見つかりません。</div>;
  }

  return (
    <div>
      <h2>プロフィール</h2>
      <p>ID: {data.id}</p>
      <p>名前: {data.name}</p>
      <p>メールアドレス: {data.email}</p>
    </div>
  );
};

export default Profile;

React Router v6 と React Redux の組み合わせ

送信側コンポーネント (SendingComponent.js)

import React from 'react';
import { useNavigate } from 'react-router-dom';
import { useSelector } from 'react-redux';

const SendingComponent = () => {
  const navigate = useNavigate();
  const data = useSelector((state) => state.data);

  const handleClick = () => {
    navigate('/profile', { state: { data } });
  };

  return (
    <div>
      <button onClick={handleClick}>プロフィールページへ移動</button>
    </div>
  );
};

export default SendingComponent;

受信側コンポーネント (Profile.js)

import React from 'react';
import { useLocation } from 'react-router-dom';

const Profile = () => {
  const location = useLocation();
  const data = location.state?.data;

  if (!data) {
    return <div>データが見つかりません。</div>;
  }

  return (
    <div>
      <h2>プロフィール</h2>
      <p>ID: {data.id}</p>
      <p>名前: {data.name}</p>
      <p>メールアドレス: {data.email}</p>
    </div>
  );
};

export default Profile;



React Router でプログラム的にナビゲーション時にデータを渡す:その他の方法

Context API を使用する

送信側コンポーネント (SendingComponent.js)

import React, { useContext } from 'react';
import { useNavigate } from 'react-router-dom';

const MyContext = React.createContext({ data: null });

const SendingComponent = () => {
  const navigate = useNavigate();
  const [data, setData] = React.useState({
    id: 1,
    name: 'John Doe',
    email: '[email protected]',
  });

  const handleClick = () => {
    navigate('/profile', { state: { data } });
  };

  return (
    <MyContext.Provider value={{ data }}>
      <div>
        <button onClick={handleClick}>プロフィールページへ移動</button>
      </div>
    </MyContext.Provider>
  );
};

export default SendingComponent;

受信側コンポーネント (Profile.js)

import React, { useContext } from 'react';
import { useLocation } from 'react-router-dom';

const MyContext = React.createContext({ data: null });

const Profile = () => {
  const location = useLocation();
  const { data } = useContext(MyContext);

  if (!data) {
    return <div>データが見つかりません。</div>;
  }

  return (
    <div>
      <h2>プロフィール</h2>
      <p>ID: {data.id}</p>
      <p>名前: {data.name}</p>
      <p>メールアドレス: {data.email}</p>
    </div>
  );
};

export default Profile;

URL パラメータを使用して、ナビゲーション時にデータを渡すこともできます。

送信側コンポーネント (SendingComponent.js)

import React from 'react';
import { useNavigate } from 'react-router-dom';

const SendingComponent = () => {
  const navigate = useNavigate();
  const data = {
    id: 1,
    name: 'John Doe',
    email: '[email protected]',
  };

  const handleClick = () => {
    navigate('/profile', {
      pathname: '/profile',
      search: `?id=${data.id}&name=${data.name}&email=${data.email}`,
    });
  };

  return (
    <div>
      <button onClick={handleClick}>プロフィールページへ移動</button>
    </div>
  );
};

export default SendingComponent;

受信側コンポーネント (Profile.js)

import React from 'react';
import { useLocation } from 'react-router-dom';

const Profile = () => {
  const location = useLocation();
  const queryString = new URLSearchParams(location.search);
  const id = queryString.get('id');
  const name = queryString.get('name');
  const email = queryString.get('email');

  if (!id || !name || !email) {
    return <div>データが見つかりません。</div>;
  }

  return (
    <div>
      <h2>プロフィール</h2>
      <p>ID: {id}</p>
      <p>名前: {name}</p>
      <p>メールアドレス: {email}</p>
    </div>
  );
};

export default Profile;

カスタムフック (useNavigateWithData.js)

import React from 'react';
import { useNavigate } from 'react-router-dom';

const useNavigateWithData = () => {
  const navigate = useNavigate();

  const navigateWithData = (path, data) => {
    navigate(path, { state: { data } });
  };

  return navigateWithData;
};

export default useNavigateWithData;

送信側コンポーネント (SendingComponent.js)

import React from 'react';
import useNavigateWithData from './useNavigateWithData';

const SendingComponent = () => {
  const navigateWithData = useNavigateWithData();
  const data = {
    id: 1,

reactjs react-router react-redux


「Tag Error: React JSX Style Tag Error on Render」を撃退!React JSX スタイルタグのエラー徹底解説

React で JSX スタイルタグを使用する際、まれに "Tag Error: React JSX Style Tag Error on Render" というエラーが発生することがあります。このエラーは、スタイルタグの構文ミスや設定問題などが原因で発生します。本記事では、このエラーの原因と解決策を分かりやすく解説します。...


React/ReduxとReact-Intl:パフォーマンスとスケーラビリティを兼ね備えた多言語アプリ開発

このアーキテクチャは、以下のコンポーネントで構成されています。Reactコンポーネント: アプリケーションのUIを構築します。Reduxストア: アプリケーションの状態を管理します。React-Intl: アプリケーションを多言語化するために使用されます。...


React、Webpack、Webpack Dev Serverで発生する「Webpack can't find module if file named jsx」エラーの解決策

React、Webpack、Webpack Dev Server を使用しているときに、webpack can't find module if file named jsx というエラーが発生することがあります。これは、Webpack が JSX ファイルを正しく処理できないことを示しています。...


Reactアプリケーションにおけるサービス:種類、メリット、使用例、React-Fluxとの関係、サンプルコード、その他の方法

コードのモジュール化: サービスは、特定の機能を担当する独立したコードの塊です。これにより、コードをより整理しやすくなり、理解と保守が容易になります。再利用性: サービスは、複数のコンポーネントで再利用することができます。これにより、コードの重複を減らし、開発時間を短縮することができます。...


React + TypeScript で発生するエラー「Binding element 'children' implicitly has an 'any' type.ts(7031)」の原因と解決策

Reactアプリケーションを TypeScript で開発していると、Binding element 'children' implicitly has an 'any' type. ts(7031) というエラーが発生することがあります。これは、JSX 要素の children プロパティに渡される値の型が TypeScript コンパイラによって正しく推論できないことを示しています。...


SQL SQL SQL SQL Amazon で見る



React Router v6でuseNavigate Hookを使う

このチュートリアルでは、React Routerを使用してプログラム的にナビゲートする方法についていくつかの方法を紹介します。React Router v6では、useNavigate Hookを使用してプログラム的にナビゲートできます。これは、関数コンポーネントでナビゲーションロジックを簡単に実装できる便利な方法です。