みかづきブログ・カスタム

基本的にはちょちょいのほいです。

Expoでアプリがフォアグラウンドになったときの処理を書く 📱

ことの発端

Expoで作ったアプリがフォアグラウンドになったタイミング、すなわちiOSアプリでいうところのviewWillEnterForegroundをどう書くのか、React Nativeのドキュメントで調べたところ、

import { useRef, useState, useEffect } from 'react';
import { AppState, AppStateStatus } from 'react-native';

const appState = useRef(AppState.currentState);
const [appStateVisible, setAppStateVisible] = useState(appState.current);

useEffect(() => {
  const subscription = AppState.addEventListener('change', (nextAppState: AppStateStatus) => {
    if (appState.current.match(/inactive|background/) && nextAppState === 'active') {
      // フォアグラウンドになった際の処理を書く
    }

    appState.current = nextAppState;
    setAppStateVisible(appState.current);
  });

  return () => {
    subscription.remove();
  };
}, []);

という感じで書けばOKということがわかりました。

reactnative.dev

早速、Expoでつくったアプリに導入してみたところ、ここの部分にエラーが出ました。

setAppStateVisible(appState.current); // → Property 'remove' does not exist on type 'void'.

AppState.addEventListenerの戻り値がvoidなことが原因です。


原因と対策

参照していたドキュメントのバージョンが0.67のもので、Expoで使っているreact-nativeが0.64.3だったことが原因でした。
改めて0.63のドキュメントを確認すると、

import { useEffect, useRef } from 'react';
import { AppState, AppStateStatus } from 'react-native';

const appState = useRef(AppState.currentState);

useEffect(() => {
  AppState.addEventListener('change', handleAppStateChange);

  return () => AppState.removeEventListener('change', handleAppStateChange);
}, []);

function handleAppStateChange(nextAppState: AppStateStatus) {
  if (appState.current.match(/inactive|background/) && nextAppState === 'active') {
    // フォアグラウンドになった際の処理を書く
  }

  appState.current = nextAppState;
}

と、AppState.addEventListenerの戻り値のremoveではなく、AppState.removeEventListenerを叩いています。

reactnative.dev

そして、こちらの書き方で問題なく動作しました。

変更されたタイミングを知るべく、順番に確認していくと、どうやら0.65で変更が入った模様です。

reactnative.dev

さらに調査を進めると、そもそもExpoのドキュメントにあっさりと答えが書いてありました。なんてこった。

https://docs.expo.dev/versions/latest/react-native/appstate/docs.expo.dev


結論

Expoが最新のReact Nativeを使っているとは限らない、というか開発元が違うのでほぼほぼ古いバージョンを使っているはずなので、React NativeのドキュメントよりもExpoのドキュメントを調べた方が良い。React Nativeのドキュメントで調べるときはバージョンに注意。というごくごく当たり前のことを改めて心に刻みました。