[React] 왜 Error Boundary는 비동기 코드 에러를 잡지 못할까?

Jnary·2024년 9월 12일
0

React

목록 보기
17/17
post-thumbnail

Error Boundary 소개

  • 목적
    • 에러로 인해 망가진 컴포넌트 트리를 대체할 UI 표시
    • react 렌더링 도중 js 에러 발생 시 컴포넌트 트리 전체가 마운트 해제 (빈화면) ← 방지
  • 구현
    • 클래스형 컴포넌트로 구현

      class ErrorBoundary extends React.Component<Props, State>

    • getDerivedStateFromError 대체 UI 표시

    • componentDidCatch 상세 에러 정보 기록

      → 혹은 react-error-boundary 라이브러리 설치

  • 과정
    • 렌더링 도중 throw된 에러 catch
  • 한계 : 다음과 같은 에러 포착 X
    • 이벤트 핸들러
      const handleClick = () => {
      	throw Error (..)
      }
      // Error Boundary가 포착 X
    • 비동기적 코드
      • fetch(axios) 도중 발생하는 네트워크 에러는?
      • 왜 안 될까? → JavaScript 구조를 알 필요가 있다
    • 서버 사이드 렌더링
    • 자식에서가 아닌 에러 경계 자체에서 발생하는 에러

JavaScript 구조

  • call stack 함수가 호출될 때 생기는 실행 컨텍스트가 쌓이는 영역
  • 실행 컨텍스트 코드가 실행되는 환경, 변수 저장위치, scope 체인, globalThis 등의 정보
  • 이벤트 루프
    • 이벤트 수집 및 처리, 큐에 대기중인 하위 작업을 처리하는 런타임 모델
    • Web API: 비동기 함수, 웹 브라우저가 제공 (ex. setTimeout, fetch, event)
  • callback queue 처리 완료된 Web API의 콜백 함수가 stack이 빌 때까지 대기하는 곳

한계 해결하기: 왜 Error Boundary가 event, fetch의 에러를 잡지 못할까?

  • 받아줄 try-catch 가 없다
  • react 렌더링과 비동기 코드의 실행 컨텍스트가 달라서!
  • fetch callback은 React 렌더링의 실행 컨텍스트가 전부 완료되고 나서 따로 생성
  • Error Boundary: React 렌더링의 실행 컨텍스트에서 발생한 것만 캐치
  • 해결방법
    • 에러 처리를 React 렌더링의 실행 컨텍스트로 끌고오면 돼!
      const [error, setError] = useState();
      if (error) throw error;   // React 렌더링 과정에서 throw
      
      fetch.. = async() => {
      	try { ... }
      	catch { setError(true); }
      }
    • 유명한 데이터 fetching 라이브러리(react-query, SWR) 은 해당 기능 알아서 제공 → error 객체를 따로 주는 이유: React 렌더링의 실행 컨텍스트로 끌고와야하기 때문

프로젝트에 적용하기

  • 에러에 대응 가능한 앱으로 설계
    • 기능 별 발생 가능한 에러를 switch case로 처리
    • 특정 기능 에러 발생 → 망가질 컴포넌트까지만 감싸기 (최소한으로)
    • 컴포넌트 트리 구조에 따라 top-down 방식으로 식별
  • 직접 에러 발생시키고 사용자 입장이 되어 관찰
profile
숭실대학교 컴퓨터학부 21

0개의 댓글

관련 채용 정보