こんにちはフロントエンドエンジニアの指田です。
コロナの影響でフルリモートになって1か月ほど経ちました。
運動不足気味です。
さて、今回はレスポンシブ対応で利用するメディアクエリをReact Context APIを使って共有・取得がシンプルに実装できたので紹介します。
Context APIについて
簡単に言うとpropsで渡さなくても、コンポーネント間で共有する方法を提供しているAPIになります。
詳しくはReactの公式を確認いただければと思います!
reactjs.org
メディアクエリについて
今回、ブレークポイントの設定・取得は「react-responsive」を使います。
Hookになっているので使いやすいです。
github.com
そして、ブレークポイントはこちらになります。
- 560px未満をスマホと設定
- 960px未満をタブレットと設定
さっそく実装を見てみましょう
// MediaQuery.tsx import React, { useContext } from 'react' import { useMediaQuery } from 'react-responsive' const MediaQueryContext = React.createContext({ isSmartPhone: false, isTablet: false, isMobile: false, isPc: false }) export const MediaQueryProvider: React.FC = ({ children }) => { const isSmartPhone = useMediaQuery({ maxWidth: 559 }) const isTablet = useMediaQuery({ minWidth: 560, maxWidth: 959 }) const isMobile = isSmartPhone || isTablet const isPc = !isMobile return ( <MediaQueryContext.Provider value={{ isSmartPhone, isTablet, isMobile, isPc }} > {children} </MediaQueryContext.Provider> ) } export const useDeviceType = () => useContext(MediaQueryContext)
まずはContext
とProvider
、useContext
でメディアクエリを取得するための関数を作成します。
Context
はexport
せずに隠蔽します。
また、MediaQueryProvider
はFunctionComponentで定義してuseMediaQuery
にてブレークポイントを設定します。
これでほぼ実装はお終いです。
// App.tsx import { MediaQueryProvider } from './MediaQuery' render( <MediaQueryProvider> <App /> </MediaQueryProvider>, document.querySelector('#app') )
さきほどのMediaQueryProvider
でアプリケーションを囲います。
これでどのコンポーネントでも利用できるようになります。
// HogePage.tsx import { useDeviceType } from './MediaQuery' const HogePage: React.FC = () => { const { isSmartPhone, isTablet, isMobile, isPc } = useDeviceType() return ( ︙ ) } export default HogePage
コンポーネントでuseDeviceType
を利用してメディアクエリを取得して完了です!
まとめ
最初の実装はCustom Hookで作成していましたが、コンポーネント間でもっと簡単に共有したいと思いContext APIを利用しました。
他にも色々な用途(認証、翻訳等)でContext APIは利用できそうです。
※社内に展開したら認証処理はこの形に変更されました。