React Routerでアクティブリンクを実装して、SPA(シングルページアプリケーション)の使いやすさを向上させよう!
React Router でアクティブリンクを実装する方法
NavLink コンポーネントを使う
NavLink
コンポーネントは、React Router v6 で導入された新しいコンポーネントで、アクティブなリンクを簡単に実装することができます。
import { NavLink } from 'react-router-dom';
const NavBar = () => {
return (
<nav>
<NavLink to="/" activeClassName="active">ホーム</NavLink>
<NavLink to="/about" activeClassName="active">概要</NavLink>
<NavLink to="/contact" activeClassName="active">お問い合わせ</NavLink>
</nav>
);
};
上記のコードでは、NavLink
コンポーネントに to
と activeClassName
プロップを渡しています。
to
プロップは、リンク先のパスを指定します。activeClassName
プロップは、リンクがアクティブなときに付与される CSS クラス名を指定します。
useActive フックを使う
useActive
フックは、React Router v6 で導入された新しいフックで、リンクがアクティブかどうかを判定することができます。
import { useLocation, useNavigate } from 'react-router-dom';
const NavBar = () => {
const location = useLocation();
const navigate = useNavigate();
const isActive = (path) => {
const currentPath = location.pathname;
return currentPath === path;
};
return (
<nav>
<a href="/" className={isActive('/') ? 'active' : ''}>ホーム</a>
<a href="/about" className={isActive('/about') ? 'active' : ''}>概要</a>
<a href="/contact" className={isActive('/contact') ? 'active' : ''}>お問い合わせ</a>
</nav>
);
};
上記のコードでは、useLocation
フックと useNavigate
フックを使って、現在のパスとナビゲーション関数を取得しています。
isActive
関数は、引数で渡されたパスが現在のパスと一致するかどうかを判定します。- リンクの
className
プロパティには、isActive
関数の返値に基づいてactive
クラスを付与しています。
どちらの方法を使うべきか
どちらの方法を使うべきかは、状況によって異なります。
- シンプルなナビゲーションバーの場合は、
NavLink
コンポーネントを使うのがおすすめです。 - より多くのカスタマイズが必要な場合は、
useActive
フックを使うのがおすすめです。
- アクティブリンクを実装する際には、アクセシビリティにも配慮することが重要です。
- スクリーンリーダーユーザーのために、
aria-current
属性を使用することができます。
アクティブリンクの実装例
import { NavLink } from 'react-router-dom';
const NavBar = () => {
return (
<nav>
<NavLink to="/" activeClassName="active">ホーム</NavLink>
<NavLink to="/about" activeClassName="active">概要</NavLink>
<NavLink to="/contact" activeClassName="active">お問い合わせ</NavLink>
</nav>
);
};
import { useLocation, useNavigate } from 'react-router-dom';
const NavBar = () => {
const location = useLocation();
const navigate = useNavigate();
const isActive = (path) => {
const currentPath = location.pathname;
return currentPath === path;
};
return (
<nav>
<a href="/" className={isActive('/') ? 'active' : ''}>ホーム</a>
<a href="/about" className={isActive('/about') ? 'active' : ''}>概要</a>
<a href="/contact" className={isActive('/contact') ? 'active' : ''}>お問い合わせ</a>
</nav>
);
};
説明
- 上記の例では、
active
という CSS クラス名がリンクがアクティブなときに付与されます。 - この CSS クラスを定義して、アクティブなリンクのスタイルを設定することができます。
useLocation
フックを使って、現在のパスを取得します。useNavigate
フックを使って、ナビゲーション関数を取得します。
カスタムコンポーネントを使って、独自のロジックでアクティブリンクを実装することができます。
import { useLocation } from 'react-router-dom';
const Link = ({ to, children }) => {
const location = useLocation();
const isActive = location.pathname === to;
return (
<a href={to} className={isActive ? 'active' : ''}>
{children}
</a>
);
};
const NavBar = () => {
return (
<nav>
<Link to="/">ホーム</Link>
<Link to="/about">概要</Link>
<Link to="/contact">お問い合わせ</Link>
</nav>
);
};
この例では、Link
というカスタムコンポーネントを作成しています。このコンポーネントは、to
と children
プロップを受け取ります。
children
プロップは、リンクのテキストコンテンツを指定します。
React Router v5 の withRouter HOCを使う
React Router v5 には、withRouter
という Higher-Order Component (HOC) が用意されていました。この HOC を使って、コンポーネントに router
プロップを注入することができます。
import { withRouter } from 'react-router-dom';
const Link = ({ to, children, router }) => {
const isActive = router.pathname === to;
return (
<a href={to} className={isActive ? 'active' : ''}>
{children}
</a>
);
};
const NavBar = () => {
return (
<nav>
<Link to="/">ホーム</Link>
<Link to="/about">概要</Link>
<Link to="/contact">お問い合わせ</Link>
</nav>
);
};
export default withRouter(NavBar);
この例では、withRouter
HOC を使って Link
コンポーネントに router
プロップを注入しています。
router
プロップには、現在のルーティング情報が含まれています。isActive
変数は、router.pathname
とto
プロップを比較して、現在のパスがリンク先のパスと一致するかどうかを判定します。
React Router v4 の LinkActive コンポーネントを使う
React Router v4 には、LinkActive
というコンポーネントが用意されていました。このコンポーネントは、activeClassName
プロップを受け取り、リンクがアクティブなときに付与される CSS クラス名を指定することができます。
import { LinkActive } from 'react-router-dom';
const NavBar = () => {
return (
<nav>
<LinkActive to="/" activeClassName="active">ホーム</LinkActive>
<LinkActive to="/about" activeClassName="active">概要</LinkActive>
<LinkActive to="/contact" activeClassName="active">お問い合わせ</LinkActive>
</nav>
);
};
この例では、LinkActive
コンポーネントを使って、リンクに activeClassName
プロップを指定しています。
注意事項
- React Router v6 では、
withRouter
HOC とLinkActive
コンポーネントは非推奨となっています。 - これらの方法を使用する場合は、React Router のドキュメントで最新の情報を確認してください。
javascript reactjs ecmascript-6