Reactで、追従ヘッダーがヘッダーの高さより下の位置にスクロールしたときに背景色を変える実装

公開日:

目次

Reactで、追従ヘッダーがヘッダーの高さより下の位置にスクロールしたときに背景色を変える実装

Reactで、追従ヘッダーがヘッダーの高さより下の位置にスクロールしたときに背景色を変えるヘッダーコンポーネントを実装したので、備忘録を兼ねてブログを残したいと思います。 実際に実装したReact Componentがこちらです。

// header.js

import React, { useEffect, useState, useRef } from "react"
import { useElementHeight } from "../hook"
import { getScrollTop } from "../common/util"

const Header = () => {
const [elm, height] = useElementHeight()
const [scroll, setScroll] = useState(0)

const handleScroll = () => {
  setScroll(getScrollTop())
}

const classNames = (...classes) => {
  return classes.filter(Boolean).join(" ")
}

useEffect(() => {
  window.addEventListener("scroll", handleScroll)
  return () => {
  window.removeEventListener("scroll", handleScroll)
}
}, [])

return (
  <header
    className={classNames(
    scroll &gt; height ? "bg-white text-primary" : "bg-transparent text-white",
    "flex justify-between fixed w-full py-4 px-4 sm:px-8 z-20 transition-colors"
)}
  ref={elm}
&gt;
{...省略}

)
}

export default Header

</header
// hook/index.js

import { useEffect, useState, useRef } from "react";

export const useElementHeight = () => {
  const heightInspectedEl = useRef(null);
  const [height, setHeight] = useState(0);

useEffect(() => {
  if (heightInspectedEl?.current) {
    const { height } = heightInspectedEl.current.getBoundingClientRect();
    setHeight(height);
  }
}, [heightInspectedEl]);

  return [heightInspectedEl, height];
}

詳しくみていきましょう。

要素の高さを取得するcustom hook

まず、要素の高さを取得するカスタムフックを作成します。hook/index.js の記述が作成したカスタムフックです。useRef を使用して作成しています。

Headerコンポーネント

次にHeaderコンポーネントをみていきます。

const [scroll, setScroll] = useState(0)

const handleScroll = () => {
  setScroll(getScrollTop())
}

ここで、現在のスクロール量を取得して、scroll という state にセットしています。

className={classNames(
scroll > height ? "bg-white text-primary" : "bg-transparent text-white",
"flex justify-between fixed w-full py-4 px-4 sm:px-8 z-20 transition-colors"
)}

そして、上記の部分で、ヘッダーの高さよりスクロール量のが大きい場合と小さい場合でスタイルを分けています。

まとめ

今回、Reactのカスタムフックというのを実装してみたのですが、ロジックをフックに切り分けることでとても見やすくスッキリわかりやすいコードを書くことができました。カスタムフックは調べてみると色々あるようなので他のフックも実装して更にReactについて理解を深めていきたいです。