Expo Routerでオブジェクトを渡す
Expo Routerを使用して画面間でオブジェクトを渡す際、画像URLを含む複雑なデータやネストされたオブジェクトを扱うと問題が発生します。URLパラメータには制限があり、以下のケースでうまく動作しません:
- 画像URLのような特殊文字を含むデータ
- 階層化されたオブジェクト構造
- 日付など特定のデータ型
- 大規模なデータオブジェクト
以下の実践的な解決策を解説します。
✅ 方法1:JSON文字列化でオブジェクトを渡す(シンプルな解決策)
データをJSON文字列に変換して渡す方法です。シンプルなデータ構造に適しています。
jsx
// 送信側
const getDetails = (item) => {
router.push({
pathname: `/details/${item.id}`,
params: { data: JSON.stringify(item) }
});
};
// 受信側
export default function DetailsScreen() {
const { data } = useLocalSearchParams();
const item = JSON.parse(data || '{}');
return <Text>{item.title}</Text>;
}
注意事項
JSON.stringify
で長大な文字列を生成しないでください- 機密データは含めないこと(URLに可視化されます)
- 型変換に注意(例: 日付は文字列に変換されます)
✅ 方法2:グローバル状態管理を使用(公式推奨)
React Navigation公式で推奨される方法です。React ContextやZustandなどを活用します。
jsx
// Zustandストア例 (store.js)
import create from 'zustand'
const useItemStore = create((set) => ({
currentItem: null,
setCurrentItem: (item) => set({ currentItem: item }),
}));
// 送信側
const getDetails = (item) => {
useItemStore.getState().setCurrentItem(item);
router.push(`/details/${item.id}`);
};
// 受信側
export default function DetailsScreen() {
const { id } = useLocalSearchParams();
const item = useItemStore(state => state.currentItem);
if (!item) return <Text>Loading...</Text>;
return <Image source={{ uri: item.imageURL }} />;
}
メリット
- URL長制限の影響なし
- 複雑なオブジェクト・データ型を保持可能
- ページリロード時も状態保持可能(永続化ライブラリと併用)
✅ 方法3:URLクエリパラメータで基本データを渡す
シンプルなプリミティブ値のみを渡す必要がある場合の手法です。
jsx
// 送信側
const getDetails = (item) => {
router.push(`/details?id=${item.id}&title=${encodeURIComponent(item.title)}`);
};
// 受信側
export default function DetailsScreen() {
const { id, title } = useLocalSearchParams();
return <Text>ID: ${id}, Title: ${title}</Text>;
}
制限事項
- 日本語などのマルチバイト文字には
encodeURIComponent
必須 - 画像URLなどの長い文字列には不向き
- ネストした構造は表現不可能
状況別ベストプラクティス
ユースケース | 推奨方法 | 理由 |
---|---|---|
シンプルな小さなオブジェクト | JSON文字列化 | 実装が簡単 |
複雑なオブジェクト | グローバル状態管理 | URL制限を回避可能 |
IDのみ渡し後方取得 | URLパラメータ | 最も標準的 |
機密データ扱う場合 | 状態管理 | URLにデータが露出しない |
💡 総合アドバイス:
中規模以上のアプリケーションでは、状態管理を使用する方法が最もスケーラブルで安全です。Expo Routerは内部的にReact Navigationを使用しているため、公式ドキュメントでも状態管理を推奨しています。JSON文字列化はプロトタイプ開発時の応急処置に向いていますが、プロダクションコードでは依存しないようにしましょう。