React & React Native/라이브러리 활용

[RN] React Native 디바이스 네트워크 연결 상태 관리 @react-native-community/netinfo 이해하고 설정하기-2 : 특정 페이지에서만 체크

adjh54 2024. 11. 21. 20:00
728x170
해당 글에서는 디바이스 네트워크 연결 상태 관리를 위해 @react-native-community/netinfo 라이브러리를 활용하여, 특정 페이지에서만 제외하는 방법에 대해 알아봅니다.

 

💡 [참고] 해당 글을 읽어보기 전에 이전에 작성한 글을 읽어보시면 도움이 됩니다.
 

[RN] React Native 디바이스 네트워크 연결 상태 관리 이해하고 설정하기 : @react-native-community/netinfo

해당 글에서는 디바이스의 네트워크 상태가 연결/미연결 인지 확인을 하기 위한 목적으로 @react-native-community/netinfo 라이브러리를 설정하고 사용하는 방법에 대해서 확인합니다.    1) @react-nativ

adjh54.tistory.com

 

1) 모든 페이지에서 네트워크 체크


💡 모든 페이지에서 네트워크 체크

- 해당 경우는 모든 페이지에서 발생하는 네트워크 연결 끊김에 대해서 체크하는 공통 로직 처리를 수행하였습니다.

1. DeviceInfoUtil.ts


💡 DeviceInfoUtil.ts

- 아래와 같이 @react-native-community/netinfo라이브러리를 사용하여서 리스너를 구성하였습니다.
- 리스너에서는 연결이 끊긴 경우에 Alert 창을 통해서 화면상에 출력하도록 구성이 되어 있습니다.
import NetInfo, { NetInfoSubscription } from "@react-native-community/netinfo";

class DeviceInfoUtil {
	/**
   * 현재 디바이스의 '네트워크 연결상태'를 리스너로 등록하여 '변경(네트워크 상태)'될때 수행이 됩니다.
   * 해당 이벤트는 디바이스 연결이 되거나 연결이 종료되었을때 한번 수행됩니다.
   *
   * @return {NetInfoSubscription} 네트워크 객체
   */
  checkDeviceNetConListener = (): NetInfoSubscription => {
      const unsubscribe: NetInfoSubscription = NetInfo.addEventListener(state => {
          if (!state.isConnected) {
              Alert.alert("네트워크 연결이 끊겼습니다.", " 디바이스 연결 상태를 확인해주세요.");
          } else {
              // console.log("최초 네트워크가 연결되었습니다.")
          }
      });
      return unsubscribe;
  }
}

 

 

2. App.ts


💡 App.ts

- 앱 실행시 해당 리스너를 등록시켜 주며, 앱이 종료되는 경우에 clean-up 과정을 통해서 해당 리스너를 해제하는 형태로 구성하였습니다.
const App = () => {
	useEffect(() => {
	
		// [STEP1] '디바이스 네트워크 연결상태' 리스너 등록
		const _unsubscribe = DeviceInfoUtil.checkDeviceNetConListener();
		
		// clean-up
		return () => {
			_unsubscribe();					// 디바이스 네트워크 연결상태에 대한 리스너를 해제합니다.
		};
	},[])
}

export default App;

 

3. 결과 확인


 💡 결과 확인

- 아래와 같이 네트워크 연결이 종료되었을때 팝업이 출력되도록 구성하였습니다.

https://adjh54.tistory.com/210

 

 

 

 

2) 특정 페이지 내에서만 네트워크 체크


💡 특정 페이지 내에서만 네트워크 체크

- 기존의 공통적으로 모든 페이지에 대해 네트워크 연결에 대해 체크하는 부분이 아닌 ‘특정 페이지’에서 네트워크 체크를 제외하는 로직이 필요하게 되어서 해당 부분을 구성하였습니다.

 

1. NetworkContext.tsx


💡 NetworkContext.tsx

- React의 Context API를 활용하여 네트워크 연결 상태 관리를 위한 컨텍스트를 생성합니다.
- NetworkContext를 사용함으로써, 앱의 어느 부분에서든 네트워크 상태 체크를 쉽게 제어할 수 있으며, 특정 화면에서 네트워크 체크를 제외하는 요구사항을 간편하게 구현할 수 있습니다.

 

💡 NetworkContext 사용예시

1. NetworkContext 생성
- React의 createContext를 사용하여 네트워크 상태 관리를 위한 컨텍스트를 만듭니다.

2. NetworkProvider 컴포넌트
- 네트워크 상태를 관리하고, 하위 컴포넌트에 상태와 상태 변경 함수를 제공합니다.

3. 네트워크 상태 감지
- useEffect 훅을 사용하여 NetInfo.addEventListener를 등록하고, 네트워크 연결이 끊어졌을 때 알림을 표시합니다.

4. useNetwork 훅
- 이 훅을 통해 다른 컴포넌트에서 NetworkContext를 쉽게 사용할 수 있습니다.
// NetworkContext.tsx
import React, { createContext, useState, useContext, useEffect } from 'react';
import NetInfo, { NetInfoSubscription } from '@react-native-community/netinfo';
import { Alert } from 'react-native';

// 1. createContext를 사용하여 네트워크 상태 관리를 위한 컨텍스트를 만듭니다.
const NetworkContext = createContext({
    isNetworkCheckEnabled: true,                        // 네트워크 상태 연결 여부 
    setNetworkCheckEnabled: (enabled: boolean) => { }   // 네트워크 상태 연결 상태 변경
});

/**
 * 2. 네트워크 상태를 관리하고, 하위 컴포넌트에 상태와 상태 변경 함수를 제공합니다.
 * @param param0 
 * @returns 
 */
export const NetworkProvider = ({ children }: { children: any }) => {

    const [isNetworkCheckEnabled, setNetworkCheckEnabled] = useState(true);     // 네트워크 연결 상태 체크 여부 

    /**
     * 3. NetInfo.addEventListener를 등록하고, 네트워크 연결이 끊어졌을 때 알림을 표시합니다.
     * - isNetworkCheckEnabled 상태를 통해서 
     */
    useEffect(() => {
        let unsubscribe: NetInfoSubscription | null = null;
        if (isNetworkCheckEnabled) {
            // 리스너를 등록합니다.
            unsubscribe = NetInfo.addEventListener(state => {
                // 네트워크 연결이 되지 않았을 경우 Alert을 출력합니다.
                if (!state.isConnected) {
                    Alert.alert("네트워크 연결이 끊겼습니다.", "디바이스 연결 상태를 확인해주세요.");
                }
            });
        }
        return () => {
            // 리스너 clean-up
            if (unsubscribe) {
                unsubscribe();
            }
        };
    }, [isNetworkCheckEnabled]);

    return (
        <NetworkContext.Provider value={{ isNetworkCheckEnabled, setNetworkCheckEnabled }}>
            {children}
        </NetworkContext.Provider>
    )
}

// 4. 이 훅을 통해 다른 컴포넌트에서 NetworkContext를 쉽게 사용할 수 있습니다.
export const useNetwork = () => useContext(NetworkContext);

 

 

[ 더 알아보기 ]

💡 React 내에 Context API


- React에서 제공하는 상태 관리 도구로, 컴포넌트 트리 전체에 데이터를 효율적으로 전달할 수 있게 해 줍니다.
- 테마, 인증 상태, 언어 설정 등 애플리케이션 전반에 걸쳐 공유되어야 하는 데이터를 관리하는 데 유용합니다.
- 하지만 모든 상황에 적합한 것은 아니며, 컴포넌트 재사용성을 해칠 수 있으므로 적절한 상황에서 사용해야 합니다.
특징 설명
전역 상태 관리 프롭스 드릴링(props drilling) 없이 컴포넌트 트리 전체에 데이터를 전달할 수 있습니다.
간편한 사용 createContext(), Provider, useContext() 훅을 통해 쉽게 구현할 수 있습니다.
성능 최적화 필요한 컴포넌트에서만 context를 구독하여 불필요한 리렌더링을 방지할 수 있습니다.
동적 업데이트 Provider의 value prop을 통해 context 값을 동적으로 업데이트할 수 있습니다.

 

2. App.tsx


💡App.tsx

- 위에서 구현한 NetworkProvider를 호출하여 App 태그 내에 아래와 같이 추가하였습니다.
- 해당 경우에서는 기본적으로 모든 페이지에서 네트워크 체크가 수행이 됩니다.
import { NetworkProvider, useNetwork } from './common/context/NetworkContext';

const App = () => {
	return (
		// Redux-Store
		<Provider store={Store}>
			{/* Redux-Persist */}
			<PersistGate persistor={persistor}>
				{/* =============== NetworkProvider 추가 ===================== */}
				<NetworkProvider>
					{/* Stack Navigation */}
					<NavigationContainer>
						{/* Code Spliting */}
						<Suspense fallback={<></>}>
							{/* Stack Navigation Element */}
							<StackNavigator appState={appStateVisible} />
						</Suspense>
					</NavigationContainer>
				</NetworkProvider>
			</PersistGate>
		</Provider>
	);
}
export default App;

 

 

3. 특정 페이지에서 네트워크 체크 제외 : TestScreen.tsx


💡 특정 페이지에서 네트워크 체크 제외 : TestScreen.tsx

- 해당 페이지에서는 네트워크 통신 없이도 수행이 되도록 해야 하기에 해당 페이지에 체크를 수행하지 않도록 하였습니다.

 

💡 사용 예시

- 아래와 같이 TestScreen에서 네트워크 체크를 수행하지 않도록 구성하였습니다.

- NetworkContext 내에서 구성한 useNetwork hook을 선언하여, 네트워크 체크를 수행하지 않도록 하는 setNetworkCheckEnabled 메서드를 불러옵니다.
- 해당 페이지가 렌더링 될 때 네트워크 체크 상태를 비활성화하고, 해당 페이지를 떠날 경우 다시 활성화를 합니다.
import { useNetwork } from "../../common/context/NetworkContext";

const TestScreen = ({ route, navigation, appState }: CommonType.CommonProps) => {
    const { setNetworkCheckEnabled } = useNetwork();

    useEffect(() => {
        setNetworkCheckEnabled(false);              // 해당 화면에서 네트워크 체크 비활성화
    }, []);

    return () => {
        setNetworkCheckEnabled(true);               // 네트워크 화면 벗어날 때 다시 활성화
    }
}
export default TestScreen;

 

 

[ 더 알아보기 ]

💡 해당 페이지가 부모 페이지인 경우 하위 페이지가 있다면 모두 적용을 해야 할까?


- 자식 컴포넌트들에 대해서는 별도로 네트워크 체크를 비활성화할 필요가 없습니다.
- NetworkProvider를 사용한 방식에서는 상위 컴포넌트(StudyScreen)에서 네트워크 체크를 비활성화하면, 그 하위의 모든 자식 컴포넌트들에도 자동으로 적용됩니다. React의 Context API의 특성 때문입니다.
- Context는 컴포넌트 트리 전체에 데이터를 제공하므로, StudyScreen에서 설정한 네트워크 체크 상태가 모든 하위 컴포넌트에 자동으로 전파됩니다.

 

 

 

오늘도 감사합니다. 😀

 

 

 

 

그리드형