🍣

【ReactNative】端末の向き変更を検知する

2021/04/19に公開

はじめに

今回はReact Nativeで画面の向き(縦横)が切り替わった際の処理についての私的メモです。
やり方は2通りあるので、それぞれの記法の違いについて紹介していきます。

前提

以下のバージョンとします。

  • react-native@0.63.3

バージョンが最新ではありませんが、基本的なイベント処理で対応できる内容のため、
最新(もしくは古いバージョン)でも動作するかと思います。

①onLayoutを使う

技術記事などで使用例が多いのがこちらのパターンです。
最上位のコンポーネントにonLayoutイベントを設定しておくことで、レイアウトが変更された時(≒画面の向きが変わった時)のイベントを捕まえることができます。

import React from 'react';
import { FC, useCallback } from 'react';
import { View } from 'react-native';

const Sample: FC = () => {
    const handleLayout = useCallback(() => {
        console.log('レイアウト変更')
    }, []);
    
    return (
        <View onLayout={handleLayout}>
            {/** 色々と要素を記載している */}
        </View>
    )
}

複雑にスタイルを変更したりする作りのコンポーネントでなければこの書き方で問題ないです。
ただ、onLayoutwidth,heightの変更以外(x,y)でも呼ばれるため、縦横の変化以外で呼ばれる可能性がある点に注意です。

②Dimensionsのイベントを使う

対してDimensionsを使ったパターンが以下になります。
こちらはDimensionsのイベントリスナーにイベントを追加する方式になっているため、アンマウント時にはイベントを削除してあげる必要があります。

従ってuseEffect(クラスコンポーネントならcomponentWillUnmount)でコンポーネントがアンマウントされるタイミングでremoveEventListenerを呼ぶようにします。

import React from 'react';
import { FC, useEffect } from 'react';
import { Dimensions, View } from 'react-native';

const Sample: FC = () => {

    useEffect(() => {
        Dimensions.addEventListener("change", ({ window }) => {
          console.log('画面サイズが変わりました')
        });
        return () => {
          Dimensions.removeEventListener("change", ({window}) => {
              console.log("イベントを削除しました");
          });
        };
      }, []);
    
    return (
        <View>
            {/** 色々と要素を記載している */}
        </View>
    )
}

onLayoutに比べて記載量が多くなっているのが若干ネックです。

まとめ

今回はReact Nativeの画面の向きが変わった際のイベント処理方法について紹介しました。
以前はreacat-native-orientationを使っていましたが、バージョンによってはうまく動作してくれないことがあったので、処理を自作した次第です。

もっといい方法があるよ!等のご意見ありましたらコメントにてお願いいたします。

Discussion