Next.jsのnext/routerは、クライアントサイドのルーティングを制御するためのさまざまなイベントとAPIを提供しています。以下は、Next.js Routerの全てのイベントと主要なAPIについての詳細です。
イベント
Next.js Routerは、ルート変更時にリスナーを設定するためのいくつかのイベントを提供します:
routeChangeStart(url, { shallow }):
ルートが変更を開始するときにトリガーされます。
引数:
url:ナビゲートするURL。
shallow:シャロー(浅い)ルーティングかどうか。
routeChangeComplete(url, { shallow }):
ルートの変更が完了するときにトリガーされます。
引数:
url:ナビゲートされたURL。
shallow:シャロー(浅い)ルーティングかどうか。
routeChangeError(err, url, { shallow }):
ルートの変更中にエラーが発生したときにトリガーされます。
引数:
err:エラーオブジェクト。
url:ナビゲートしようとしたURL。
shallow:シャロー(浅い)ルーティングかどうか。
beforeHistoryChange(url, { shallow }):
ブラウザの履歴が変更される前にトリガーされます。
引数:
url:ナビゲートするURL。
shallow:シャロー(浅い)ルーティングかどうか。
hashChangeStart(url, { shallow }):
URLのハッシュ部分が変更を開始するときにトリガーされます。
引数:
url:ナビゲートするURL。
shallow:シャロー(浅い)ルーティングかどうか。
hashChangeComplete(url, { shallow }):
URLのハッシュ部分が変更を完了するときにトリガーされます。
引数:
url:ナビゲートされたURL。
shallow:シャロー(浅い)ルーティングかどうか。
イベントの使用例
import { useEffect } from 'react';
import { useRouter } from 'next/router';
const MyComponent = () => {
const router = useRouter();
useEffect(() => {
const handleRouteChangeStart = (url, { shallow }) => {
console.log(`Route is changing to ${url} with shallow: ${shallow}`);
};
const handleRouteChangeComplete = (url, { shallow }) => {
console.log(`Route change to ${url} completed with shallow: ${shallow}`);
};
const handleRouteChangeError = (err, url, { shallow }) => {
console.error(`Route change to ${url} failed with shallow: ${shallow}`, err);
};
router.events.on('routeChangeStart', handleRouteChangeStart);
router.events.on('routeChangeComplete', handleRouteChangeComplete);
router.events.on('routeChangeError', handleRouteChangeError);
return () => {
router.events.off('routeChangeStart', handleRouteChangeStart);
router.events.off('routeChangeComplete', handleRouteChangeComplete);
router.events.off('routeChangeError', handleRouteChangeError);
};
}, [router]);
return <div>My Component</div>;
};
export default MyComponent;
API
Next.jsのnext/routerは、以下の主要なAPIを提供します:
useRouter():
ルーターオブジェクトを返し、関数コンポーネントで使用します。
使用例`
import { useRouter } from 'next/router';
const MyComponent = () => {
const router = useRouter();
const handleClick = () => {
router.push('/about');
};
return <button onClick={handleClick}>Go to About</button>;
};
export default MyComponent;
withRouter(Component):
高階コンポーネントを使用してクラスコンポーネントでルーターオブジェクトにアクセスします。
使用例:
import { withRouter } from 'next/router';
class MyComponent extends React.Component {
handleClick = () => {
this.props.router.push('/about');
};
render() {
return <button onClick={this.handleClick}>Go to About</button>;
}
}
export default withRouter(MyComponent);
router.push(url, as, options):
指定されたURLにナビゲートします。
引数:
url:目的のURL。
as:ブラウザのURLバーに表示されるURL(オプション)。
options:設定オプション(例:shallow)。
使用例:
router.push('/about');
router.replace(url, as, options):
履歴に新しいエントリを追加せずに、現在のURLを置き換えます。
引数はrouter.pushと同じです。
使用例
router.replace('/about');
router.reload():
現在のルートを再読み込みします。
使用例:
router.reload();
router.back():
履歴の前のページに戻ります。
使用例:
router.back();
router.prefetch(url, as, options):
将来のナビゲーションを高速化するために、指定されたURLを事前取得します。
引数:
url:目的のURL。
as:ブラウザのURLバーに表示されるURL(オプション)。
options:設定オプション(オプション)。
使用例
router.prefetch('/about');
router.beforePopState(callback):
「戻る」ボタンの動作をカスタマイズします。
引数:
callback:状態をポップするかどうかを決定するためのブール値を返す関数。
使用例:
router.beforePopState(({ url, as, options }) => {
// 特定のURLを許可
if (url !== '/forbidden') {
return true;
}
// 特定のURLを禁止
return false;
});
(Shallow Routing)補足説明
更新 URL(例えばクエリパラメータを変更する)だけでなく、ページ全体を再レンダリングせずに特定のコンポーネントだけを更新します。
例:
import { useRouter } from 'next/router';
const MyComponent = () => {
const router = useRouter();
const handleShallowRouting = () => {
// クエリパラメータ "counter" を更新し、ページを再レンダリングせずに変更を適用
router.push({
pathname: router.pathname,
query: { ...router.query, counter: (parseInt(router.query.counter || '0', 10) + 1).toString() },
}, undefined, { shallow: true });
};
return (
<div>
<p>Current Counter: {router.query.counter || '0'}</p>
<button onClick={handleShallowRouting}>Increase Counter</button>
</div>
);
};
export default MyComponent;
詳細な説明
router.pushの第三引数に{ shallow: true }を指定:
これにより、URLの変更が発生してもページ全体の再レンダリングが防がれます。
Next.jsは既にロードされているコンポーネントをそのまま維持し、必要な部分のみを更新します。
なぜ浅路由を使うのか?
・パフォーマンスの向上:
ページ全体の再レンダリングを避けることで、ユーザーエクスペリエンスが向上します。
必要最低限の更新のみを行うため、パフォーマンスが向上します。
・ユーザーインタラクションの簡素化:
クエリパラメータやページ内の状態を簡単に変更でき、ページ遷移の感覚をユーザーに与えません。