フォーカスされた画面が変更されたときに関数を呼び出す
このガイドでは、画面のフォーカス時に関数を呼び出したり、画面に何かをレンダリングする方法を説明します。これは、ユーザーがタブナビゲーターで特定の画面を再訪したときに追加のAPI呼び出しを行う場合や、アプリ内でのユーザーイベントを追跡する場合に役立ちます。
いくつかのアプローチがあります。
- イベントリスナーを使用して`'focus'`イベントをリスンします。
- react-navigationが提供する`useFocusEffect`フックを使用します。
- react-navigationが提供する`useIsFocused`フックを使用します。
`'focus'`イベントリスナーによるアクションのトリガー
イベントリスナーを使用して`'focus'`イベントをリスンすることもできます。イベントリスナーを設定した後、画面がアンマウントされたときにもイベントのリスンを停止する必要があります。
このアプローチでは、画面にフォーカスされた場合にのみアクションを呼び出すことができます。これは、分析のために画面表示をログに記録するなどのアクションを実行する場合に役立ちます。
例
import * as React from 'react';
import { View } from 'react-native';
function ProfileScreen({ navigation }) {
React.useEffect(() => {
const unsubscribe = navigation.addListener('focus', () => {
// The screen is focused
// Call any action
});
// Return the function to unsubscribe from the event so it gets removed on unmount
return unsubscribe;
}, [navigation]);
return <View />;
}
イベントリスナーAPIの詳細については、ナビゲーションイベントガイドを参照してください。
ほとんどの場合、リスナーを手動で追加する代わりに`useFocusEffect`フックを使用することをお勧めします。詳細については以下を参照してください。
`useFocusEffect`フックによるアクションのトリガー
React Navigationは、画面がフォーカスされたときに効果を実行し、フォーカスが外れたときにクリーンアップするフックを提供します。これは、イベントリスナーの追加、画面がフォーカスされたときにAPI呼び出しでデータを取得する場合、または画面が表示されたときに実行する必要があるその他の任意のアクションなど、多くの場合に役立ちます。
これは、ページのフォーカスが外れたときに何かを停止する場合(ビデオやオーディオファイルの再生を停止する場合や、ユーザーの位置の追跡を停止する場合など)に特に便利です。
import { useFocusEffect } from '@react-navigation/native';
function Profile({ userId }) {
const [user, setUser] = React.useState(null);
useFocusEffect(
React.useCallback(() => {
const unsubscribe = API.subscribe(userId, (user) => setUser(data));
return () => unsubscribe();
}, [userId])
);
return <ProfileContent user={user} />;
}
`useFocusEffect`のドキュメントで詳細を参照してください。
`useIsFocused`フックを使用した画面の再レンダリング
React Navigationは、画面がフォーカスされているかどうかを示すブール値を返すフックを提供します。
画面がフォーカスされている場合は`true`を、コンポーネントがフォーカスされなくなった場合は`false`を返します。これにより、ユーザーが画面にいるかどうかに基づいて、条件付きで何かをレンダリングできます。
`useIsFocused`フックを使用すると、画面にフォーカスとアンフォーカスがされた際にコンポーネントが再レンダリングされます。このフックを使用すると、画面のフォーカスとアンフォーカス時に不要なコンポーネントの再レンダリングが発生する可能性があります。これは、フォーカス時に呼び出しているアクションの種類によっては問題を引き起こす可能性があります。したがって、再レンダリングをトリガーする必要がある場合にのみ、このフックを使用することをお勧めします。イベントの購読やデータの取得などの副作用には、上記の方法を使用してください。
import * as React from 'react';
import { Text } from 'react-native';
import { useIsFocused } from '@react-navigation/native';
function Profile() {
// This hook returns `true` if the screen is focused, `false` otherwise
const isFocused = useIsFocused();
return <Text>{isFocused ? 'focused' : 'unfocused'}</Text>;
}
この例は、`useIsFocused` APIドキュメントにも記載されています。