React Nativeで、 iOS、Android、そしてWebページに対応したメディアクエリの実装方法
Post on:2019年11月20日
iOS、Android、そしてWebページに対応したメディアクエリをReact Nativeで実装する方法を紹介します。
Media Queries with React Native for iOS, Android, and Web
by Evan Bacon
下記は各ポイントを意訳したものです。
※当ブログでの翻訳記事は、元サイト様にライセンスを得て翻訳しています。
はじめに
Expo Webの開発中にわたし達が抱えていた大きな課題は、メディアクエリを誰がどうやって実装するかです。
メディアクエリは、デバイスの状態に基づいて切り替えることができるスタイルのルールで、スクリーンのさまざまなサイズや向きで機能するレスポンシブ対応のレイアウトを簡単に構築するための重要なポイントです。
Reactにはメディアクエリの素晴らしいライブラリがすでに数多くありますが、ユニバーサルシステムの最適なアプローチはネイティブにポリフィルを行い、既存のエコシステムを再利用することだと考えました。その結果は@expo/match-mediaで、お気に入りのライブラリの大部分を使用することができます。
具体的に説明すると、Expoに付属しているネイティブのScreen Orientation moduleを使用して、向きが変わった時にクエリを実行します。また、スクリーン分割機能を使用するAndroidデバイスのスクリーンサイズも監視します。
実装方法
ここではExpoアプリでreact-responsiveを使用する方法を紹介します。もちろんreadmeには常に最新の情報が記載されていますが、内容はおそらくあまり変わらないでしょう😁
最初にパッケージをインストールします。
1 |
yarn add @expo/match-media react-responsive |
次に、プロジェクトのルートでパッケージをインポートします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
import '@expo/match-media' // Unleash the demo :D import { useMediaQuery } from "react-responsive"; export default function App() { const isTabletOrMobileDevice = useMediaQuery({ maxDeviceWidth: 1224, // alternatively... query: "(max-device-width: 1224px)" }); if (isTabletOrMobileDevice) { return (<Text>Hi Mobile Users 👋</Text>) } return (<Text>👋 Hello Desktop People</Text>) } |
簡単ですね、これで完了です。
React Responsiveでできることの詳細についてはドキュメントをご覧ください。これだけでクエリを取得できます!
まとめ
一つのjsファイルにまとめました。
コードはMITライセンスで、下記の通りです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
import "./build"; import React from "react"; import { useMediaQuery } from "react-responsive"; import { View, Platform, Text } from "react-native"; function Header({ style, ...props } = {}) { return ( <Text accessibilityLabel="header" style={[ { fontWeight: "bold", marginBottom: 24, fontSize: Platform.select({ web: "2.25rem", default: 2.25 * 16 }) }, style ]} {...props} /> ); } export default function App() { const isDesktopOrLaptop = useMediaQuery({ query: "(min-device-width: 1224px)" }); const isBigScreen = useMediaQuery({ query: "(min-device-width: 1824px)" }); const isTabletOrMobile = useMediaQuery({ query: "(max-width: 1224px)" }); const isTabletOrMobileDevice = useMediaQuery({ query: "(max-device-width: 1224px)" }); const isPortrait = useMediaQuery({ query: "(orientation: portrait)" }); const isRetina = useMediaQuery({ query: "(min-resolution: 2dppx)" }); return ( <View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}> <Header>Device Test!</Header> {isDesktopOrLaptop && ( <> <Text>You are a desktop or laptop</Text> {isBigScreen && <Text>You also have a huge screen</Text>} {isTabletOrMobile && <Text>You are sized like a tablet or mobile phone though</Text>} </> )} {isTabletOrMobileDevice && <Text>You are a tablet or mobile phone</Text>} <Text> Your are in {isPortrait ? "portrait" : "landscape"} orientation </Text> {isRetina && <Text>You are retina</Text>} </View> ); } |
sponsors