반응형
해당 글에서는 디바이스 네트워크 연결 상태 관리를 위해 @react-native-community/netinfo 라이브러리를 활용하여, 특정 페이지에서만 제외하는 방법에 대해 알아봅니다.
💡 [참고] 해당 글을 읽어보기 전에 이전에 작성한 글을 읽어보시면 도움이 됩니다.
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. 결과 확인
💡 결과 확인
- 아래와 같이 네트워크 연결이 종료되었을때 팝업이 출력되도록 구성하였습니다.
반응형
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에서 설정한 네트워크 체크 상태가 모든 하위 컴포넌트에 자동으로 전파됩니다.
오늘도 감사합니다. 😀
반응형