最近 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 を実装できました。