해당 글은 지난 포스팅인 #1 에러 살펴보기 에서 시작합니다:)
프론트엔드 쪽에서 발생할 수 있는 에러 상황에 대해서 고려한 위의 글을 작성했을 때 쯤에 네트워크 연결이 원할하지 않은 상황을 몇 번 겪었었다.
그 이유로는 필자는 LG U+를 사용했었기 때문에...
그래서 유저의 네트워크가 온전히 동작하지 않는 offline
의 상황에서 대응 하는 작업의 필요성을 느끼게 되어 구현하게 되었다.
처음 서버가 동작하지 않을 때 유저에게 안내하는 페이지를 만들려고 했을 때에 어떻게 구현해야할지 2가지 방법을 두고 고민하였다.
현재 풀고자 하는 문제는 네트워크가 통신해야하는 상황이지만 인터넷이 동작하지 않아 발생하는 문제이기 때문에 해당 문제가 발생하였는지 여부를 확인하여 화면을 보여주는 것이 좋을 것이라고 생각하였다.
만약 해당 방법으로 구현 한다면,
현재 서버가 online인지 여부를 표시하는 전역 상태를 하나 만들고 -> 네트워크 통신이 발생할 때마다 네트워크 상태를 체크한다 -> 만약 offline이 되면 상태값을 변경하여 안내화면을 보여준다
라는 플로우를 가지게 될 것이다.
하지만 , 해당 방법은 전역으로 관리해야할 상태 값이 하나 늘어난다는 단점으로 인해 팀원들에게 기각되었다.
마치 스낵바를 구현할 때 처럼 전역으로 네트워크의 offline, online상태 여부를 계속해서 확인하는 이벤트를 등록 한 후 offline이 되었을 때 관련 화면을 기존의 페이지에 덮어서 보여주는 것이다.
해당 방법은 하나의 컴포넌트 안에서 서버가 Offline인지 여부를 확인하는 로직과 UI component가 한 곳에 모아져 있기 때문에 관리 부분에서 장점이 있다.
이러한 장점 때문에 조리복 프로젝트에서는 2번의 방법을 사용하여 기능을 구현하기로 하였다.
조리복 프로젝트는 NEXT
프레임워크를 사용하여 개발을 하고 있다.
해당 조건이기 때문에 useState
와 useEffect
를 사용하여 기능을 구현할 것이다
useState
를 통해 생성한다 const [isServerOffline, setIsServerOffline]
= useState(false);
window에 addEventListener를 통해 이벤트를 등록하여 offline
여부를 감지해 상태를 변동시킨다.
offline일 경우 isServerOffline
을 true로 online일 경우에는 false로 지정해준다
const handleServerOfflineState = () => {
window.addEventListener('offline', () => {
setIsServerOffline(true);
});
window.addEventListener('online', () => {
setIsServerOffline(false);
});
};
useEffect(() => {
handleServerOfflineState();
}, []);
useEffect(() => {
handleServerOfflineState();
return () => {
window.removeEventListener('online', handleServerOfflineState);
window.removeEventListener('offline', handleServerOfflineState);
}
}, []);
return
한다if (isSeverWork) {
return (
<Container>
<Title>서버 에러 발생</Title>
<div>잠시 후에 다시 시도해주세요</div>
</Container>
);
}
현재 구현부에서는 Container에 스타일 조정을 통해서 (화면을 꽉 차게 하여) 기존에 보여주고 있는 콘텐츠를 덮도록 구현하였다
window에 이벤트를 등록하긴 했지만,
위에 구현된 컴포넌트가 특정한 컴포넌트에 종속적인 컴포넌트라면 해당 컴포넌트에서 벗어났을 때에는 제대로 동작하지 않을 수 있다. 예를 들어, Home page에 종속적인 컴포넌트라면 유저가 다른 페이지로 이동했을 때에 네트워크 연결이 off가 되면 서버 에러 화면이 나오지 않을 것이다.
그렇기 때문에 모든 페이지에서 동작할 수 있도록 전역으로 작동할 수 있겠금 동작하게 하는 것이 중요하다 마치 snackBar
처럼 말이다
그래서 리액트에서는 App.tsx에 넣어주는 것도 좋은 방법이다.
현재 조리복 프로젝트는 Next로 개발을 하고 있기 때문에
_app.tsx
에 새롭게 만든 컴포넌트를 넣어주었다.
<Provider>
<QueryClientProvider client={queryClient}>
<Hydrate state={pageProps.dehydratedState}>
<Layout>
<Component {...pageProps} />
</Layout>
<NetworkError/> -> network 상태에 대응하는 컴포넌트
<SnackBar />
</Hydrate>
</QueryClientProvider>
</Provider>