どうも!かけちまるです!
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> </> ) }
react-scroll
www.npmjs.com
react-scroll を導入し超簡単に画面内のスクロールを実装しよう | fwywd(フュード)powered by キカガク
fwywd.com
`NextRouter` was not mounted
nextjs.org
おわり
フィードバックを送信
記事についてのフィードバックはTwitterかお問い合わせフォームから受け付けております。