みかづきブログ・カスタム

基本的にはちょちょいのほいです。

ページのスクロールとリサイズを管理するシンプルなカスタムフックをつくる 🖱

f:id:kimizuka:20210416093201p:plain

以前作ったカスタムフックが複雑すぎたのでシンプル版を作りました。

blog.kimizuka.org

useScroll.tsx

import { useEffect, useState } from 'react';

export default function useResize() {
  const [ scrollTop, setScrollTop ] = useState(0);
  const [ scrollLeft, setScrollLeft] = useState(0);

  useEffect(() => {
    window.removeEventListener('scroll', handleScroll);
    window.addEventListener('scroll', handleScroll, {
      passive: true
    });

    handleScroll();

    return () => {
      window.removeEventListener('scroll', handleScroll);
    }
  }, []);

  function handleScroll() {
    setScrollTop(window.scrollY);
  }

  return { scrollLeft, scrollTop }
}

useResize.tsx

import { useEffect, useState } from 'react';

export default function useResize() {
  const [ windowWidth, setWindowWidth ] = useState(0);
  const [ windowHeight, setWindowHeight ] = useState(0);

  useEffect(() => {
    window.removeEventListener('resize', handleResize);
    window.addEventListener('resize', handleResize, {
      passive: true
    });

    handleResize();

    return () => {
      window.removeEventListener('resize', handleResize);
    }
  }, []);

  function handleResize() {
    setWindowWidth(window.innerWidth);
    setWindowHeight(window.innerHeight);
  }

  return { windowWidth, windowHeight }
}

使い方

import useResize from '../hooks/useResize';
import useScroll from '../hooks/useScroll';
import ListPageTemplate from '../components/templates/IndexPageTemplate';
import { useEffect } from 'react';

export default function ListPage({ models }) {
  const { windowWidth, windowHeight } = useResize();
  const { scrollTop } = useScroll();

  return (
    <IndexPageTemplate
      windowWidth={ windowWidth }
      windowHeight={ windowHeight }
      scrollTop={ scrollTop }
    />
  );
}

こんな感じで使います。