概要
TanStack Routerは画面遷移時に 任意の状態(state) を添えて画面遷移することができます。(クエリパラメータを添付する方法については触れません。)
ただし、TypeScriptで開発していると、公式ドキュメントのサンプルコードをそのまま使うと型エラーが発生したため、本記事では対処方法を解説します。
開発環境
- TypeScript
- TanStack Router v1
- React + Vite
発生した型エラー
以下のようにnavigate
のstate
に値を渡したとき、TypeScriptの型エラーが発生
navigate({
to: '/groups/$groupId/reports',
params: { groupId: report.groupId },
state: {
userId: "sample",
},
});
エラー内容
state
に渡すプロパティが型として未定義なため発生するエラーです。
オブジェクト リテラルは既知のプロパティのみ指定できます。'userId' は型 'NonNullableUpdater<HistoryState>' に存在しません。ts(2353)
解決方法
TypeScriptで型安全にstate
を使うためには、型を拡張してやる必要があります。具体的には@tanstack/react-router
モジュールを拡張し、HistoryState
インターフェースに値を定義してやります。こうすることで、上記の型エラーは消えるはずです。
// main.tsxなど、routerインスタンスを定義しているファイル
import { createRouter } from '@tanstack/react-router';
import { routeTree } from './routeTree';
export const router = createRouter({ routeTree });
// 型拡張。TS環境ならすでにこちらの記述は存在するはず
declare module '@tanstack/react-router' {
interface Register {
router: typeof router;
}
// 以下を追加。stateに渡せるプロパティを明示的に定義
interface HistoryState {
userId?: string;
}
}
実装例
簡単な実装例を示します。
遷移元:stateを渡して画面遷移
import { useNavigate } from '@tanstack/react-router';
export const UserList = () => {
const navigate = useNavigate();
const handleNavigate = () => {
navigate({
to: '/users/$userId',
params: { userId: '123' },
state: {
userId: '123',
},
});
};
return <button onClick={handleNavigate}>詳細へ</button>;
};
遷移先:stateを受け取る
useRouterState Hookを使用してstate
を受け取る。
import { useRouterState } from '@tanstack/react-router';
export const UserDetail = () => {
const userId = useRouterState({
select: (state) => state.location.state.userId,
});
return (
<div>
<h1>ユーザー詳細</h1>
{userId && <p>ユーザーID: {state.userId}</p>}
</div>
);
};
まとめ
-
navigate({ state })
で一時的な状態を画面遷移に添えられる - TypeScriptで使う場合は、
HistoryState
をdeclare module
で拡張する必要がある -
useRouterState
を使うと、stateを安全に受け取れる
サーチパラメータでURLを汚さずに表示制御や一時的な情報共有が可能になります。参考になれば幸いです。
参考リンク