useHistory から useNavigate への移行:React Router v6 での変更点
問題点
React Router を使用している際に、以下のようなエラーが発生する場合があります:
Attempted import error: 'useHistory' is not exported from 'react-router-dom'
このエラーは、React Router のバージョンに関連する問題です。特に、v5 から v6 へのメジャーアップデートにおいて、useHistory
フックが非推奨となり、新しい useNavigate
フックに置き換えられました。
解決策
方法1: React Router v6 で useNavigate を使用する(推奨)
React Router v6 では、useHistory
の代わりに useNavigate
を使用します。
import { useNavigate } from 'react-router-dom';
function MyComponent() {
const navigate = useNavigate();
const handleClick = () => {
// 基本的なナビゲーション
navigate('/home');
// 置換ナビゲーション(履歴に追加しない)
navigate('/home', { replace: true });
// state を渡す場合
navigate('/user', { state: { id: 123, name: 'John' } });
};
return (
<button onClick={handleClick}>
ホームへ移動
</button>
);
}
方法2: 履歴操作の互換性
v5 の useHistory
が提供していた goBack
, goForward
, go
メソッドも、useNavigate
で実現できます。
import { useNavigate } from 'react-router-dom';
function NavigationButtons() {
const navigate = useNavigate();
return (
<>
<button onClick={() => navigate(-2)}>
2ページ戻る
</button>
<button onClick={() => navigate(-1)}>
戻る
</button>
<button onClick={() => navigate(1)}>
進む
</button>
<button onClick={() => navigate(2)}>
2ページ進む
</button>
</>
);
}
方法3: React Router v5 を使い続ける場合
何らかの理由で v6 への移行が難しい場合は、v5 の最新バージョン(5.2.0以上)を使用することで useHistory
を引き続き利用できます。
npm install react-router-dom@5.2.0
WARNING
v5 のサポートは将来的に終了する可能性があるため、長期的には v6 への移行を検討することをお勧めします。
実装例
以下は、実際のコードで useHistory
から useNavigate
に移行する具体例です。
移行前 (v5):
import { useHistory } from 'react-router-dom';
function UserForm() {
const history = useHistory();
const confirm = (e) => {
history.push('/success');
};
// ... その他のコード
}
移行後 (v6):
import { useNavigate } from 'react-router-dom';
function UserForm() {
const navigate = useNavigate();
const confirm = (e) => {
navigate('/success');
// または置換したい場合
// navigate('/success', { replace: true });
};
// ... その他のコード
}
よくある使用シナリオ
async function handleSubmit(formData) {
try {
const result = await submitToAPI(formData);
navigate('/success', {
replace: true,
state: { message: '登録が成功しました' }
});
} catch (error) {
navigate('/error', { state: { error: error.message } });
}
}
function CheckoutProcess() {
const navigate = useNavigate();
const { user } = useAuth();
const proceedToPayment = () => {
if (user.isLoggedIn) {
navigate('/payment');
} else {
navigate('/login', {
state: { from: '/checkout' }
});
}
};
return (
<button onClick={proceedToPayment}>
決済へ進む
</button>
);
}
まとめ
React Router v6 では、ナビゲーションのための API が刷新され、useHistory
から useNavigate
へと変更されました。この変更により、コードはより直感的で一貫性のあるものになっています。新しいプロジェクトでは v6 を使用し、既存のプロジェクトについては計画的な移行を推奨します。
INFO
React Router の最新情報や詳細な移行ガイドについては、公式ドキュメントを参照してください。