今回は React Routerでよく使用されるuseNavigateについて詳しく解説していきます。
useNavigate とは?
React Router の useNavigate は、Reactアプリケーションでプログラムによる画面遷移を実現するための強力な Hook です。以前は history API を使用していましたが、現在は useNavigate が推奨される方法となっています。
基本的な使い方
import { useNavigate } from 'react-router-dom';
function LoginComponent() {
const navigate = useNavigate();
const handleLogin = async (e) => {
e.preventDefault();
// ログイン処理
const success = await loginUser();
if (success) {
// ログイン成功時にダッシュボードへ遷移
navigate('/dashboard');
}
};
return (
<form onSubmit={handleLogin}>
{/* フォームの内容 */}
</form>
);
}
useNavigate の便利な使い方
1. データを渡しながら画面遷移
const navigate = useNavigate();
// ユーザー情報を次の画面に渡す
navigate('/profile', {
state: {
userId: 123,
username: "John"
}
});
2. 履歴の操作
// 1つ前の画面に戻る
navigate(-1);
// 2つ前の画面に戻る
navigate(-2);
// 1つ先の画面に進む
navigate(1);
useNavigate の実践的なユースケース
開発でよく使用される useNavigate のユースケースを実例とともに解説します。
1. ログイン/認証後のリダイレクト
function LoginForm() {
const navigate = useNavigate();
const [error, setError] = useState('');
const handleSubmit = async (e) => {
e.preventDefault();
try {
const result = await loginUser(credentials);
if (result.success) {
navigate('/dashboard', {
replace: true, // ブラウザの履歴を置き換え(戻るボタンでログイン画面に戻れなくする)
state: { userName: result.user.name }
});
}
} catch (error) {
setError('ログインに失敗しました');
}
};
return <form onSubmit={handleSubmit}>{/* フォームの内容 */}</form>;
}
2. フォーム送信後の遷移
function OrderForm() {
const navigate = useNavigate();
const handleSubmit = async (formData) => {
const orderId = await submitOrder(formData);
// 注文完了ページへ遷移し、注文情報を渡す
navigate(`/order/complete/${orderId}`, {
state: {
orderDetails: formData,
timestamp: new Date().toISOString()
}
});
};
return (/* フォームの内容 */);
}
3. 権限チェックと条件付きリダイレクト
function AdminDashboard() {
const navigate = useNavigate();
const { user } = useAuth();
useEffect(() => {
if (!user || !user.isAdmin) {
navigate('/forbidden', {
replace: true,
state: { message: '管理者権限が必要です' }
});
}
}, [user, navigate]);
return (/* ダッシュボードの内容 */);
}
4. 複数ステップのフォーム処理
function MultiStepForm() {
const navigate = useNavigate();
const { step, formData } = useFormContext();
const handleNext = () => {
if (step === 1) {
navigate('/form/step2', { state: { formData } });
} else if (step === 2) {
navigate('/form/review', { state: { formData } });
}
};
const handleBack = () => {
navigate(-1); // 前のステップに戻る
};
return (/* フォームの内容 */);
}
5. データ検索と結果ページへの遷移
function SearchComponent() {
const navigate = useNavigate();
const handleSearch = (searchParams) => {
const queryString = new URLSearchParams(searchParams).toString();
navigate({
pathname: '/search',
search: `?${queryString}`,
});
};
return (/* 検索フォームの内容 */);
}
6. エラー発生時のリダイレクト
function ProductDetail() {
const navigate = useNavigate();
useEffect(() => {
const fetchProduct = async () => {
try {
const product = await getProduct(id);
if (!product) {
navigate('/404', { replace: true });
}
} catch (error) {
navigate('/error', {
replace: true,
state: { error: error.message }
});
}
};
fetchProduct();
}, [id, navigate]);
return (/* 商品詳細の内容 */);
}
7. ショッピングカートのチェックアウトフロー
function CartCheckout() {
const navigate = useNavigate();
const { cart } = useCart();
const handleCheckout = () => {
if (cart.items.length === 0) {
navigate('/cart', {
replace: true,
state: { message: 'カートが空です' }
});
return;
}
if (!isUserLoggedIn()) {
navigate('/login', {
state: {
returnTo: '/checkout',
message: 'チェックアウトにはログインが必要です'
}
});
return;
}
navigate('/checkout');
};
return (/* チェックアウトボタンなど */);
}
8. フィルタリングと並び替え
function ProductList() {
const navigate = useNavigate();
const location = useLocation();
const handleFilter = (filters) => {
navigate({
pathname: location.pathname,
search: `?${new URLSearchParams(filters).toString()}`,
}, {
replace: true // URLの履歴を残したくない場合
});
};
return (/* 商品一覧とフィルターUI */);
}
これらのユースケースを適切に組み合わせることで、スムーズなユーザー体験を実現できます。また、パフォーマンスやSEOを考慮して、適切な場面で navigate を使用することが重要です。
ついでにnavigate(0) の特徴
さて、ここからが本題の navigate(0) についてです。
navigate(0) とは?
navigate(0) は現在のページを完全にリロードする機能です。window.location.reload() と同様の動作をしますが、React Router の文脈の中で使用できる利点があります。
navigate(0) の使用例
function DataListComponent() {
const navigate = useNavigate();
const handleRefresh = () => {
// データを最新の状態に更新
navigate(0);
};
return (
<div>
<button onClick={handleRefresh}>
データを更新
</button>
{/* データ一覧の表示 */}
</div>
);
}
navigate(0) のユースケース
- フォームの送信後にページをリフレッシュしたい場合
- データの変更後に最新の状態を表示したい場合
- アプリケーションの状態をリセットしたい場合
navigate(0) vs window.location.reload()
両者は似たような動作をしますが、いくつかの違いがあります:
- 履歴の扱い
- navigate(0) は React Router の文脈の中で動作する
- window.location.reload() はブラウザネイティブの機能
- React の文脈
- navigate(0) は React のライフサイクルを考慮している
- window.location.reload() は単純なページリロード
まとめ
useNavigate と navigate(0) は、モダンな React アプリケーションで画面遷移とページリロードを扱うための強力なツールです。
- useNavigate はプログラムによる画面遷移に
- navigate(0) は現在のページの完全なリロードに
- 両者を組み合わせることで、よりスムーズなユーザー体験を実現できます
