【React Router × TypeScript】型安全な開発を極める!`match`オブジェクトと`useParams`フックの使い分け
React、TypeScript、React Router における props の match
オブジェクトの型参照
React、TypeScript、React Router を組み合わせた開発において、コンポーネントの props として受け取る match
オブジェクトにアクセスするには、適切な型定義が必要です。このチュートリアルでは、その方法について分かりやすく解説します。
match
オブジェクトとは
必要な型定義
match
オブジェクトにアクセスするには、@types/react-router
パッケージから提供される RouteComponentProps
型を使用する必要があります。この型は、match
プロパティを含む、ルーターコンポーネントの props の型定義を提供します。
具体的な型定義例
以下のコード例は、match
オブジェクトを含む props を受け取るコンポーネントの型定義を示しています。
import React from 'react';
import { RouteComponentProps } from 'react-router-dom';
interface Props extends RouteComponentProps<any> {
// 他の props
}
const MyComponent: React.FC<Props> = ({ match, ...props }) => {
// match オブジェクトを使用するコード
const userId = match.params.userId;
return <div>ユーザー ID: {userId}</div>;
};
この例では、Props
インターフェースは RouteComponentProps
型を継承しています。これにより、match
プロパティを含む、RouteComponentProps
型で定義されているすべての props にアクセスできるようになります。
注意点
match
オブジェクトは、コンポーネントがルートに直接レンダリングされていない場合、利用できない場合があります。このような場合は、useRoute
フックを使用してmatch
オブジェクトにアクセスする必要があります。RouteComponentProps
型はジェネリック型であり、P
というパラメータを持ちます。このパラメータは、match.params
プロパティの型を定義するために使用されます。上記の例では、P
はany
型に設定されていますが、より具体的な型に置き換えることもできます。
src
├── App.tsx
├── components
│ └── Profile.tsx
├── index.tsx
└── routes.ts
コード解説
1 routes.ts
このファイルは、ルーティングの設定を定義します。
import React from 'react';
import { Route, Routes } from 'react-router-dom';
import Profile from '../components/Profile';
const routes: Route[] = [
{
path: '/profile/:userId',
element: <Profile />,
},
];
export default routes;
このコードでは、/profile/:userId
というパスを持つルートを定義しています。このルートにアクセスすると、Profile
コンポーネントが表示されます。:userId
はルートパラメータであり、ユーザー ID を格納します。
2 App.tsx
このファイルは、アプリケーションのルートコンポーネントを定義します。
import React from 'react';
import { BrowserRouter } from 'react-router-dom';
import routes from './routes';
const App: React.FC = () => {
return (
<BrowserRouter>
<Routes>{routes}</Routes>
</BrowserRouter>
);
};
export default App;
このコードでは、BrowserRouter
コンポーネントを使用して、React Router をセットアップしています。routes
プロパティには、routes.ts
ファイルで定義したルート設定が渡されます。
3 Profile.tsx
このファイルは、Profile
コンポーネントを定義します。このコンポーネントは、ユーザーのプロフィール情報を表示します。
import React from 'react';
import { RouteComponentProps } from 'react-router-dom';
interface Props extends RouteComponentProps<any> {
// 他の props
}
const Profile: React.FC<Props> = ({ match, ...props }) => {
const userId = match.params.userId;
// ユーザー情報フェッチ
const user = getUser(userId);
if (!user) {
return <div>ユーザーが見つかりません。</div>;
}
return (
<div>
<h1>{user.name}</h1>
<p>メールアドレス: {user.email}</p>
</div>
);
};
export default Profile;
このコードでは、RouteComponentProps
型を使用して、match
オブジェクトを含む props を定義しています。match.params.userId
を使用して、ルートパラメータ userId
の値を取得しています。
実行
上記のコードを実行すると、以下のようになります。
- ブラウザに
http://localhost:3000/profile/123
と入力すると、ユーザー ID 123 のプロフィール情報が表示されます。 - ブラウザに
http://localhost:3000
と入力すると、空のプロフィールページが表示されます。
useParams
フックを使用した代替方法
例
import React from 'react';
import { useParams } from 'react-router-dom';
const Profile: React.FC = () => {
const { userId } = useParams();
// ユーザー情報フェッチ
const user = getUser(userId);
if (!user) {
return <div>ユーザーが見つかりません。</div>;
}
return (
<div>
<h1>{user.name}</h1>
<p>メールアドレス: {user.email}</p>
</div>
);
};
export default Profile;
このコードでは、useParams
フックを使用して、userId
という名前の URL パラメータの値を取得しています。
useParams
フックの利点
- TypeScript での型推論がより容易になる
match
オブジェクトにアクセスする必要がない- コードがより簡潔になる
match
オブジェクトを使用する利点
- ネストされたルーティングを処理する場合に役立つ
- 現在の URL パスに関する情報にアクセスできる
どちらの方法を使用するか
どちらの方法を使用するかは、個々のユースケースによって異なります。コードをより簡潔に記述したい場合は、useParams
フックを使用することをお勧めします。match
オブジェクトにアクセスする必要がある場合、またはネストされたルーティングを処理している場合は、match
オブジェクトを使用する必要があります。
useRoute
フックを使用して、現在のルートに関する情報を取得することもできます。
reactjs typescript react-router