どうも!かけちまるです!
Reactで一瞬にしてページ内リンクでスムーススクロールを実装できるreact-scroll。
しかし、react-scrollの実装はできているはずなのにスムーススクロールが機能しない。
例えば、共通ヘッダーでトップページではページ内リンク先はあるけど、下層ページにはページ内リンク先がない時はどうしようというあたりを解説します。
この記事では、
がわかります。
Next.jsで使用することを想定して説明したいと思います。
Reactでもほぼ設定方法は同じです👍
コンポーネントが別々でもしっかり動きます。
実装手順は次のような感じです。
react-scrollをインストール
npmかyarnでreact-scrollをインストールします。
ターミナル// npmの場合 npm install react-scroll // yarnの場合 yarn add react-scroll
遷移先要素にid属性をつける
次は、遷移先要素にid属性をつけます。
名前は任意の値でOK!
Next.js<section id="contact"> ・・・ </section>
react-scrollの設定を行う
Next.jsimport { Link as Scroll } from 'react-scroll' export default function Header() { return ( <> <header> ・・・ <Scroll to='contact' smooth={ true } duration={ 600 } offset={ -100 }>お問い合わせ</Scroll> ・・・ </header> </> ) }
まず、react-scrollからLinkコンポーネントをimportします。LinkコンポーネントをScrollに変更しているのは、Next.jsではnext/linkのLinkコンポーネントを使ってリンクを設定すると思うので名前が混在しないようにしています。
Scrollコンポーネントに設定するオプションの説明ですが、
| オプション | 説明 |
|---|---|
| to | 遷移先のターゲット(id属性)を設定 |
| smooth | trueにするとターゲットまでスクロールする |
| duration | スムーススクロールの時間 |
| offset | ターゲット位置に追加して〇〇px移動 |
つまり、id=”contact”要素の-100pxまで600msでスクロールしながら移動するということです。
これで通常は実装できるかと思います。
react-scrollの使い方の通り設定してもピクリともしない時の対処法の説明です。
コンテンツをフルページ表示するためにCSSでhtml、body、mainタグにheight: 100%;をあてているとreact-scrollがうまく機能しないようです。
Next.jsだと#_nextもですかね。
気づきにくいですね。
例えば、共通ヘッダーのように全てのページに読み込む場合、ページ内リンク先があったりなかったりします。
そこで、ページ内リンク先がある時はスムーススクロール
ない時はターゲット要素へページ遷移するようにしたいとします。
そんな時の対処法です。
以下のコードは、
トップページならスムーススクロールし、それ以外のページならターゲット要素へページ遷移する例です。
Next.jsimport { useRouter } from 'next/router' import Link from 'next/link' import { Link as Scroll } from 'react-scroll' export default function Header() { const router = useRouter(); return ( <> <header> ・・・ (router.pathname == '/') ? // if文でメニューを出し分ける <> <Scroll to='contact' smooth={ true } duration={ 600 } offset={ -100 }>お問い合わせ</Scroll> </> : <> <Link href={`/#contact`} legacyBehavior> <a className={header.nav}>お問い合わせ</a> </Link> </> } ・・・ </header> </> ) }
next/routerのuseRouterのpathnameで現在ページのpathを取得してif文でメニューの出し分けをしています。
Reactの場合は、どうにかしてpathを取得するとかページを識別できればいいと思います。
ここからは、react-scrollは関係なく、useRouterについてです。
もし、以下のようなエラーが出ていたら、Next.js13.4でApp Routerを採用している人かもしれません。
これは、App Routerを採用しているとuseRouterの呼び出し元が違うようです。pathを取得する際は、以下のようにすると良いと思います。
Next.jsimport { usePathname } from 'next/navigation' import Link from 'next/link' import { Link as Scroll } from 'react-scroll' export default function Header() { const pathname = usePathname(); return ( <> <header> ・・・ (pathname == '/') ? // if文でメニューを出し分ける <> <Scroll to='contact' smooth={ true } duration={ 600 } offset={ -100 }>お問い合わせ</Scroll> </> : <> <Link href={`/#contact`} legacyBehavior> <a className={header.nav}>お問い合わせ</a> </Link> </> } ・・・ </header> </> ) }
www.npmjs.com
react-scroll を導入し超簡単に画面内のスクロールを実装しよう | fwywd(フュード)powered by キカガク
fwywd.com
`NextRouter` was not mounted
nextjs.org
おわり
フィードバックを送信
記事についてのフィードバックはTwitterかお問い合わせフォームから受け付けております。