컴포넌트 에러 발생
render 함수에서 에러가 발생할 경우 리액트 어플리케이션이 종료가 됩니다. 이러한 상황에서 유용하게 사용할 수 있는 API가 있는데요, 생명주기 이벤트 중에 하나인 componentDidCatch라는 녀석입니다.
componentDidCatch(error, info) {
this.setState({
error: true
});
}
에러가 발생하면 이런 식으로 componentDidCatch가 실행되게 하고, state.error를 true로 설정하게 하고, render 함수 쪽에서 이에 따라 에러를 띄워주시면 됩니다.
이때 주의할 점이 이 componentDidMount는 컴포넌트 자신의 render 함수에서 발생하는 에러는 잡아낼 수는 없지만, 컴포넌트의 자식 컴포넌트 내부의 에러는 잡아낼 수 있습니다!
import React, { Component } from 'react';
import styles from './main.module.css';
import Button from 'react-bootstrap/Button';
const Promblematic = () => {
throw (new Error('버그가 나타났다!'));
return (
<div>
</div>
);
};
class LifeCycleTest extends Component {
state = {
number: 0,
error: false
}
constructor(props) {
super(props);
console.log('constructor');
}
componentWillMount() {
console.log('componentWillMount (deprecated)');
}
componentDidMount() {
console.log('componentDidMount');
}
shouldComponentUpdate(nextProps, nextState) {
// 5 의 배수라면 리렌더링 하지 않음
console.log('shouldComponentUpdate');
if (nextState.number % 5 === 0) return false;
return true;
}
componentWillUpdate(nextProps, nextState) {
console.log('componentWillUpdate');
}
componentDidUpdate(prevProps, prevState) {
console.log('componentDidUpdate');
}
handleIncrease = () => {
const { number } = this.state;
this.setState({
number: number + 1
});
}
handleDecrease = () => {
this.setState(
({ number }) => ({
number: number - 1
})
);
}
componentDidCatch(error, info) {
this.setState({
error: true
});
}
render() {
if (this.state.error) return (<h1>에러발생</h1>);
console.log('render');
return (
<div className={styles.layout}>
<h1>카운터</h1>
<div>값: {this.state.number}</div>
{ this.state.number === 4 && <Promblematic /> }
<Button onClick={this.handleIncrease}>+</Button>
<Button onClick={this.handleDecrease}>-</Button>
</div>
);
}
}
export default LifeCycleTest;
기존에 사용하던 생명주기 코드를 사용하는데요, 카운터의 값이 4가 되면 에러를 발생시키는 로직을 추가했습니다.
카운터가 4가 되면 에러가 발생할 수 있도록 throw new Error를 사용했는데요, 이때 에러가 발생하면 componentDidCatch에서 에러가 발생된 것을 확인하고 state의 error값을 true로 변경해 render측에서 에러발생화면으로 넘어가게 됩니다.
에러 화면에서 우측 상단의 X표시를 누르면
카운터의 컴포넌트가 위와 같은 텍스트로 변경되는 것을 확인할 수 있습니다!
리엑트를 사용할 때 렌더링 부분에서 오류가 발생하는 것을 사전에 방지를 잘 해주어야 합니다.
주로 자주 에러가 발생하는 이유는 아래와 같습니다.
1. 존재하지 않는 함수를 호출하려고 할 때(props로 받았을 줄 알았던 함수가 전달되지 않을 때)
this.props.onClick();
2. 배열이나 객체가 올줄 알았는데, 해당 객체나 배열이 존재하지 않을 때
this.props.object.value; // object is undefined
this.props.array.length; // array is undefined
이러한 에러는 render 함수에서 다음과 같은 코드를 사용함으로 방지할 수 있습니다.
render() {
if (!this.props.object || !this.props.array || this.props.array.length ===0) return null;
// object 나 array 를 사용하는 코드
}
또는 컴포넌트의 기본값을 설정하는 defaultProps를 통해서 설정하면 됩니다.
class Sample extends Component {
static defaultProps = {
onIncrement: () => console.warn('onIncrement is not defined'),
object: {},
array: []
}
}
이러한 방법으로도 에러 캐치가 되지 않을 경우에는 componentDidMount를 사용하면 됩니다!
'FrontEnd > React 기본' 카테고리의 다른 글
[React] React.js 강좌 8. 함수형 컴포넌트 props 정리 (0) | 2021.11.25 |
---|---|
[React] React.js 강좌 7. 조건부 연산자 (0) | 2021.11.25 |
[React] React.js 강좌 5. 이벤트 처리, Bind (0) | 2021.11.19 |
[React] React.js 강좌 4. 생명주기 이벤트 (0) | 2021.11.18 |
[React] React.js 강좌 3. Fragments (0) | 2021.11.18 |