유저의 인터넷이 동작하지 않을 때를 대비하자

Sally·2023년 2월 22일
1

조리복

목록 보기
4/4
post-thumbnail

해당 글은 지난 포스팅인 #1 에러 살펴보기 에서 시작합니다:)

프론트엔드 쪽에서 발생할 수 있는 에러 상황에 대해서 고려한 위의 글을 작성했을 때 쯤에 네트워크 연결이 원할하지 않은 상황을 몇 번 겪었었다.
그 이유로는 필자는 LG U+를 사용했었기 때문에...

그래서 유저의 네트워크가 온전히 동작하지 않는 offline의 상황에서 대응 하는 작업의 필요성을 느끼게 되어 구현하게 되었다.

두 가지 아이디어

처음 서버가 동작하지 않을 때 유저에게 안내하는 페이지를 만들려고 했을 때에 어떻게 구현해야할지 2가지 방법을 두고 고민하였다.

  1. 서버와의 통신을 진행할 때마다 network상태가 offline인지 확인하기

현재 풀고자 하는 문제는 네트워크가 통신해야하는 상황이지만 인터넷이 동작하지 않아 발생하는 문제이기 때문에 해당 문제가 발생하였는지 여부를 확인하여 화면을 보여주는 것이 좋을 것이라고 생각하였다.

만약 해당 방법으로 구현 한다면,
현재 서버가 online인지 여부를 표시하는 전역 상태를 하나 만들고 -> 네트워크 통신이 발생할 때마다 네트워크 상태를 체크한다 -> 만약 offline이 되면 상태값을 변경하여 안내화면을 보여준다

라는 플로우를 가지게 될 것이다.

하지만 , 해당 방법은 전역으로 관리해야할 상태 값이 하나 늘어난다는 단점으로 인해 팀원들에게 기각되었다.

  1. 전역으로 이벤트를 등록해 네트워크 상태를 감지하여 화면 보여주기

마치 스낵바를 구현할 때 처럼 전역으로 네트워크의 offline, online상태 여부를 계속해서 확인하는 이벤트를 등록 한 후 offline이 되었을 때 관련 화면을 기존의 페이지에 덮어서 보여주는 것이다.

해당 방법은 하나의 컴포넌트 안에서 서버가 Offline인지 여부를 확인하는 로직과 UI component가 한 곳에 모아져 있기 때문에 관리 부분에서 장점이 있다.

이러한 장점 때문에 조리복 프로젝트에서는 2번의 방법을 사용하여 기능을 구현하기로 하였다.

개발 환경

조리복 프로젝트는 NEXT 프레임워크를 사용하여 개발을 하고 있다.

해당 조건이기 때문에 useStateuseEffect를 사용하여 기능을 구현할 것이다

구현 STEP

  1. 서버 상태를 가지고 있을 상태값을 useState를 통해 생성한다
 const [isServerOffline, setIsServerOffline]
 = useState(false);
  1. window에 addEventListener를 통해 이벤트를 등록하여 offline여부를 감지해 상태를 변동시킨다.

    offline일 경우 isServerOffline을 true로 online일 경우에는 false로 지정해준다

const handleServerOfflineState = () => {
    window.addEventListener('offline', () => {
      setIsServerOffline(true);
    });
    window.addEventListener('online', () => {
      setIsServerOffline(false);
    });
  };
  1. useEffect를 통해 컴포넌트가 최초로 mount 될 때에 이벤트를 등록한다
useEffect(() => {
    handleServerOfflineState();
  }, []);
  • removeEventListener
    해당 페이지가 unmount 될 때에 아래와 같이 이벤트를 제거하는 과정이 필요하다
useEffect(() => {
	handleServerOfflineState();
    
    return () => {
    	window.removeEventListener('online', handleServerOfflineState);
      	window.removeEventListener('offline', handleServerOfflineState);
    }

}, []);
  1. server가 offline 상태일 경우 유저에게 보여줄 페이지를 return한다
    아닐 경우에는 <></>등을 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>

0개의 댓글