LoginSignup
1
4

More than 3 years have passed since last update.

[React]Hooks を使って window.innerWidth からブレイクポイントを計算する

Posted at

最近 React の勉強をしているんですが、Hooks の使い方と Custom Hook の作り方を身につけるためにいろいろサンプルを作っていくことにしたので、それを上げていきます。

今回はブラウザの横幅からブレイクポイントを設定するサンプルです。

デモは こちら
※ ブラウザの横幅を変えると表示が変わります。

react: 16.13.0
react-router-dom: 5.1.2
lodash: 4.17.15
typescript: 3.7.5

useBreakpoint

import { useEffect, useState } from 'react';
import lodash from 'lodash';

// ブレイクポイントを定義。Material UI を使っているので、それに合わせて作成
// https://material-ui.com/customization/breakpoints/
const getBreakpoint = (width: number): string => {
  if (width < 600) {
    return 'xs';
  }
  if (width < 960) {
    return 'sm';
  }
  if (width < 1280) {
    return 'md';
  }
  if (width < 1920) {
    return 'lg';
  }

  return 'xl';
};

const useBreakpoint = () => {
  const [innerWidth, setInnerWidth] = useState(window.innerWidth);
  // ブレイクポイントを設定
  const [breakpoint, setBreakpoint] = useState(
    getBreakpoint(window.innerWidth),
  );

  useEffect(() => {
    // resize の度に処理しないように throttle で間引く
    const calcInnerWidth = lodash.throttle(() => {
      setBreakpoint(getBreakpoint(window.innerWidth));
      setInnerWidth(window.innerWidth);
    }, 200);

    window.addEventListener('resize', calcInnerWidth);

    // アンマウント時にクリーンアップ
    return () => window.removeEventListener('resize', calcInnerWidth);
  }, []);

  return { innerWidth, breakpoint };
};

export default useBreakpoint;

useBreakpoint を使ったコンポーネント

import React, { FC } from 'react';
import useBreakpoint from 'hooks/use-breakpoint';

const UseBreakpointHook: FC = () => {
  const { innerWidth, breakpoint } = useBreakpoint();

  return (
    <>
      <div>width: {innerWidth}</div>
      <div>breakpoint: {breakpoint}</div>
    </>
  );
};

export default UseBreakpointHook;

これでブラウザの横幅を動かすと breakpoint と width が適宜変わっていく Custom Hook を実装できました。

1
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
4