에러 경계란
* 과거 리액트는 컴포넌트 내에서 발생한 에러를 정상적으로 처리 할 수 있는 방법을 제공하지 않아 이를 복구 할 수 없었습니다.
에러 경계는 새로운 컴포넌트나 자바스크립트 라이브러리가 아닌 리액트 컴포넌트 내부에서 발생하는 에러를 다루기 위한 전략적인 방법이라고 할 수 있습니다.
참고자료:
https://www.digitalocean.com/community/tutorials/react-error-boundaries
에러 경계 in React
UI 일부분에서 발생하는 자바스크립트 에러가 전체 애플리케이션을 중단해서는 안되기 때문에 React 16버전에서 에러경계라는 새로운 개념이 도입되었습니다.
자바스크립트 에러가 난 컴포넌트 대신 폴백 UI ( 사용자 설정 가능 ) 를 보여줍니다.
* 에러 경계는 다음과 같은 에러는 포착하지 않습니다.
- 이벤트 핸들러
- 비동기적 코드 ( setTimeout 이나 requestAnimationFrame 같은 )
- 서버 사이드 렌더링
- 자식 컴포넌트가 아닌 에러 경계 자체에서 발생하는 에러
에러 경계는 리액트 트리 내에서 '하위'에 존재하는 컴포넌트의 에러만을 포착합니다. 에러 경계가 에러 메시지를 렌더링하는 데에 실패한다면 에러는 그 위의 가장 가까운 에러 경계로 전파 됩니다.
에러 경계 선언 및 사용 예시 :
https://codepen.io/gaearon/pen/wqvxGa?editors=0010
에러 경계의 적절한 위치
에러 바운더리의 세분화는 프로젝트 필요에 따라 개발자에 따라 달라질 수 있다. 아래와 같은 접근법을 시행할 수 있다.
- 최상위 라우트 컴포넌트를 감싸서 전체 응용 프로그램에 대한 일반적인 에러 메시지를 표시할 수 있다.
- 각각의 컴포넌트를 에러 바운더리로 감싸서 나머지 응용 프로그램이 충돌하지 않도록 보호할 수 있다.
잡히지 않는 에러의 대한 동작
리액트 16 부터는 에러 경계에 포착되지 않는 에러는 리액트 컴포넌트 tree의 마운트가 해제된다. ( class component 이벤트 중 unmount 와 같음 )
이유는 에러를 발생시키는 UI를 그대로 두는 것 보단 제거하는 것이 낫기 때문이다.
프로덕션 환경에서는 자바스크립트 에러 리포팅 서비스를 활용하여 미처 발견하지 못한 예외 상황에 대하여 보고 받는 것도 권장하는 방법입니다.
컴포넌트 스택 추적
리액트 16버전 부터 렌더링 하는 동안 에러를 콘솔에 출력한다. 정확히 컴포넌트 트리의 어느 부분에서 에러가 발생했는지 확인 할 수 있다. ( 파일 이름과 줄 번호 확인 가능) Create React App 프로젝트의 디폴트로 동작 한다. 단 Create React App을 사용하지 않을 경우 Babel 설정으로 해야 한다. 개발 단계에서만 사용 가능하기 때문에 프로덕션 환경에서는 비활성화 해야 한다.
try/catch 블록과 에러 경계의 차이점
Try catch 블록은 명령 코드와 함께 작동하지만, 에러 바운더리는 선언 코드가 화면에 렌더링할 때이다. 예를 들어, try catch 블록은 아래 명령 코드같이 사용된다.
try { showButton();
} catch (error) {
// ...
}
반면 에러 바운더리는 선언적 코드를 아래와 같이 감싼다.
<ErrorBoundary>
<MyComponent />
</ErrorBoundary>
따라서 tree의 어딘가 setState로 인해서 componentDidUpdate 메서드에서 오류가 발생하면, 가장 가까운 에러 바운더리로 전파된다.
이벤트 핸들러
render 메소드와는 달리 이벤트 핸들러는 렌더링 중에 발생하는 이벤트가 아니다.
그렇기 때문에 핸들러의 에러는 에러 경계가 알아 챌 수 없다.
핸들러의 에러는 잡아햐 하는 경우는 자바스크립트의 try /catch 구문을 사용해야 한다.
handleClick() {
try {
// 에러를 던질 수 있는 무언가를 해야한다.
} catch (error) {
this.setState({ error });
}
}
render() {
// 에러 경계가 아닌 직접 에러 분기 처리
if (this.state.error) {
return <h1>Caught an error.</h1>
}
return <button onClick={this.handleClick}>Click Me</button>
}
'Web > React.js' 카테고리의 다른 글
[STUDY] Ref 전달하기 (0) | 2021.03.15 |
---|---|
[STUDY] 컨텍스트 (0) | 2021.03.13 |
[STUDY] 코드분할 (0) | 2021.03.10 |
[STUDY] 접근성 (0) | 2021.03.09 |
[STUDY] 리액트의 기본 개념 (0) | 2020.09.08 |
댓글