React Router でプログラム的にナビゲーション時にデータを渡す方法
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