import { useDebugValue, useEffect, useState } from 'react'; import { useNavigationSafely } from './useNavigationSafely'; /** * @name useIsFocusedSafely * @category Hooks * @kind function * @link https://github.com/react-navigation/react-navigation/blob/%40react-navigation/native%406.1.18/packages/core/src/useIsFocused.tsx * @description * 현재 화면이 포커스된 상태인지 여부를 반환해요. * * `@react-navigation/native`에서 제공하던 `useIsFocused`를 안전하게 사용할 수 있도록 만든 Hook이에요. * 이 Hook은 `@react-navigation/native` 에서 제공하는 `useIsFocused`을 기반으로, `navigation` 이나 `root` 객체가 `null`이거나 `undefined`일 때에 에러를 throw 하지 않도록 만들었어요. * `@react-navigation/native` 를 쓰지 않는 환경에서 코드가 사용 되더라도 유저가 에러를 보지 않도록 만들었어요. * * @returns {boolean} - 현재 화면의 포커스 상태를 반환해요. * @example * ```typescript * const isFocused = useIsFocusedSafely(); * console.log(isFocused); // true or false * ``` */ export function useIsFocusedSafely(): boolean { const navigation = useNavigationSafely(); const isNavigationFocused = () => navigation?.isFocused() ?? true; const [isFocused, setIsFocused] = useState(isNavigationFocused()); const valueToReturn = isNavigationFocused(); if (isFocused !== valueToReturn) { // If the value has changed since the last render, we need to update it. // This could happen if we missed an update from the event listeners during re-render. // React will process this update immediately, so the old subscription value won't be committed. // It is still nice to avoid returning a mismatched value though, so let's override the return value. // This is the same logic as in https://github.com/facebook/react/tree/master/packages/use-subscription setIsFocused(valueToReturn); } useEffect(() => { if (navigation == null) { return; } const unsubscribeFocus = navigation.addListener('focus', () => setIsFocused(true)); const unsubscribeBlur = navigation.addListener('blur', () => setIsFocused(false)); return () => { unsubscribeFocus(); unsubscribeBlur(); }; }, [navigation]); useDebugValue(valueToReturn); return valueToReturn; }