[React] 9. 라이프사이클 메서드
1. 라이프사이클 메서드 정리 ✍
1.1 render() 함수
render() {...}
- 라이프사이클 메서드 중 유일한 필수 메서드이다.
- 이 메서드 안에서
this.props와 this.state에 접근할 수 있으며, 리액트 요소를 반환한다.
예를 들어, div 태그, 컴포넌트 등
render() {...}this.props와 this.state에 접근할 수 있으며, 리액트 요소를 반환한다.예를 들어,
div 태그, 컴포넌트 등주의할점❗❗
- 이벤트 설정이 아닌 곳에서
setState를 사용하면 안되고, 브라우저의DOM에 접근해도 안된다.
DOM 정보를 가져오거나state에 변화를 줄 때는componentDidMount에서 처리해야 한다.
1.2 constructor 메서드
constructor(props) {...}
- 컴포넌트의 생성자 메서드로 컴포넌트를 만들 때 처음으로 실행되고, 초기
state를 정할 수 있다.
1.3 getDerivedStateFromProps 메서드
- 리액트 v16.3 이후에 만들어진 메서드로,
props로 받아 온 값을state에 동기화시키는 용도로 사용하고 컴포넌트가 마운트될 때와 업데이트될 때 호출된다.
static getDerivedStateFromProps(nextProps, prevState) {
if(nextProps.value !== prevState.value) { // 조건에 따라 특정 값 동기화
return { value: nextProps.value };
}
return null; // state를 변경할 필요가 없다면 null 반환
}
1.4 componentDidMount 메서드
componentDidMount() {...}
- 컴포넌트를 만들고, 첫 렌더링을 마친 후 실행하는 메서드이다.
- 이 메서드를 통해 다른
자바스크립트 라이브러리또는프레임워크의 함수를 호출,이벤트 등록,setTimeout,setInterval,네트워크 요청같은 비동기 작업 처리한다.
1.5 shouldComponentUpdate 메서드
shouldComponentUpdate(nextProps, nextState) {...}
propsorstate를 변경했을 때, 리렌더링을 시작할지 여부를 지정하는 메서드이다.- 위의 언급대로
true,false반환하며, 컴포넌트를 만들 때 이 메서드를 따로 사용하지 않으면 기본값은true를 반환한다.❗❗ - 현재
props와state는this.props와this.state로 접근하고, 새로 설정될props와state는nextProps,nextState로 접근한다.
TIP ❗❗
프로젝트 성능을 최적화할 때, 상황에 맞는 알고리즘을 사용하여 리렌더링을 방지할 때는false값을 반환하면 된다.
1.6 getSnapshotBeforeUpdate 메서드
- 리액트 v16.3 이후 만들어진 메서드로
render에서 만들어진 결과물이 브라우저에 실제로 반영되기 직전에 호출된다. - 이 메서드에서 반환하는 값은
componentDidUpdate에서 세 번째파라미터인snapshot값으로 전달받으며, 주로 업데이트하기 직전의 값을 참고할 때 사용한다.
👉 (ex. 스크롤바 위치 유지)
getSnapshotBeforeUpdate(prevProps, prevState) {
if(prevState.array !== this.state.array) {
const { scrollTop, scrollHeight } = this.list
return { scrollTop, scrollHeight };
}
}
1.7 componentDidUpdate 메서드
componentDidUpdate(prevProps, prevState, snapshot) {...}
- 리렌더링을 완료 후 실행하는 메서드로,
업데이트가 끝난 직후라서DOM관련 처리를 해도 상관없다. - 여기서
prevPropsorprevState를 사용해서 컴포넌트가 이전에 가졌던 데이터에 접근할 수 있다. - snapshot 값은
getSnapshotBeforeUpdate에서 반환한 값으로 전달받을 수 있다.
1.8 componentWillUnmount 메서드
componentWillUnmount() {...}
- 컴포넌트를 DOM에서 제거할 때 사용한다.
componentDidMount에서 등록한이벤트,타이머,직접 생성한 DOM이 있다면 여기서 제거해야 한다.
1.9 componentDidCatch 메서드
- 리액트 v16에 새롭게 생성된 메서드로, 컴포넌트 렌더링 도중에 에러가 발생했을 때
오류 UI를 보여 줄 수 있다.
componentDidCatch(error, info) {
this.setState({
error: true
});
consol.log({ error, info });
}
error는 파라미터에 어떤 에러가 발생했는지 알려주고,info는 어디에 있는 코드에서 오류가 발생했는지에 대한 정보를 담고있다.
알고 넘어가기 ❗❗
- 이 메서드는 컴포넌트 자신에게 발생하는 에러는 잡을 수 없고 자신의
this.props.children으로 전달되는 컴포넌트에서 발생하는 에러만 잡을 수 있다.
2. 라이프사이클 메서드 실습
2.1 컴포넌트 생성
src/LifeCycleSample.js를 생성하여 아래와 같이 코드를 작성했다.
//LifeCycleSample.js
class LifeCycleSample extends Component {
state = {
number: 0,
corlor: null,
}
myRef = null; // ref를 설정할 부분
constructor(props) {
super(props);
console.log('constructor');
}
static getDerivedStateFormProps(nextProps, prevState) {
console.log('getDerivedStateFromProps');
if(nextProps.color !== prevState.color) {
return { color: nextProps.color };
}
return null;
}
componentDidMount() {
console.log('componentDidMount');
}
shouldComponentUpdate(nextProps, nextState) {
console.log('shouldComponentUpdate', nextProps, nextState);
// 숫자 마지막 자리가 4면 리렌더링 안함.
return nextState.number % 10 !== 4;
}
componentWillUnmount() {
console.log('componentWillUnmount');
}
handleClick = () => {
this.setState({
number: this.setState.number + 1
});
}
getSnapshotBeforeUpdate(prevProps, prevState) {
console.log('getSnapshotBeforeUpdate');
if(prevProps.color !== this.prevProps.color) {
return this.myRef.style.color;
}
return null;
}
componentDidUpdate(prevProps, prevState, sanpshot) {
console.log('componentDidUpdate', prevProps, prevState);
if(sanpshot) {
console.log('업데이트되기 전 색상: ', sanpshot);
}
}
render() {
console.log('render');
const style = {
color: this.props.color
};
return (
<div>
<h1 style={style} ref={(ref) => this.myRef=ref}>
{this.state.number}
</h1>
<p>color: {this.props.color}</p>
<button onClick={this.handleClick}>
더하기
</button>
</div>
)
}
}
- 이 컴포넌트는 각 라이프사이클 메서드를 실행할 때마다
console.log를 출력하고, 부모 컴포넌트에서 props로 색상을 받아 버튼을 누르면 state.number 값이 1씩 증가한다.
- getDerivedStateProps는 부모에게서 받은
color 값을 state에 동기화하고 있으며, getSnapshotBeforeUpdate는 DOM에 변화가 일어나기 적진의 색상 속성을 snapshot 값으로 변환하여 이것을 componentDidUpdate에서 조회할 수 있다.
- 그리고 shouldComponentUpdate 메서드에서
state.number 값의 마지막 자리 수가 4(ex. 4, 14, 24, 34 등등)로 끝나면 리렌더링을 취소한다.
2.2 LifeCycleSample 렌더링
src/App.js 파일에 다음과 같이 코드를 작성했다.
//App.js
// 랜덤 색상 생성하는 함수
function getRandomColor() {
return '#' + Math.floor(Math.random() * 16777215).toString(16);
}
class App extends Component {
state = {
color: '#000000'
}
handleClick = () => {
this.setState({
color: getRandomColor()
});
}
render() {
return (
<div>
<button onClick={this.handleClick}>랜덤 색상</button>
<LifeCycleSample color={this.state.color}/>
</div>
);
}
}
- getRandomColor 함수로 랜덤 색상을 설정했는데,
16777215는 hex 표현으로 ffffff이다.
- 버튼을 렌더링하고, 누를 때마다
handleClidk 메서드가 호출되게 이벤트를 설정했고, 불러온 LifeCycleSample 컴포넌트에 color 값을 props로 설정한다.
src/LifeCycleSample.js를 생성하여 아래와 같이 코드를 작성했다.//LifeCycleSample.js
class LifeCycleSample extends Component {
state = {
number: 0,
corlor: null,
}
myRef = null; // ref를 설정할 부분
constructor(props) {
super(props);
console.log('constructor');
}
static getDerivedStateFormProps(nextProps, prevState) {
console.log('getDerivedStateFromProps');
if(nextProps.color !== prevState.color) {
return { color: nextProps.color };
}
return null;
}
componentDidMount() {
console.log('componentDidMount');
}
shouldComponentUpdate(nextProps, nextState) {
console.log('shouldComponentUpdate', nextProps, nextState);
// 숫자 마지막 자리가 4면 리렌더링 안함.
return nextState.number % 10 !== 4;
}
componentWillUnmount() {
console.log('componentWillUnmount');
}
handleClick = () => {
this.setState({
number: this.setState.number + 1
});
}
getSnapshotBeforeUpdate(prevProps, prevState) {
console.log('getSnapshotBeforeUpdate');
if(prevProps.color !== this.prevProps.color) {
return this.myRef.style.color;
}
return null;
}
componentDidUpdate(prevProps, prevState, sanpshot) {
console.log('componentDidUpdate', prevProps, prevState);
if(sanpshot) {
console.log('업데이트되기 전 색상: ', sanpshot);
}
}
render() {
console.log('render');
const style = {
color: this.props.color
};
return (
<div>
<h1 style={style} ref={(ref) => this.myRef=ref}>
{this.state.number}
</h1>
<p>color: {this.props.color}</p>
<button onClick={this.handleClick}>
더하기
</button>
</div>
)
}
}console.log를 출력하고, 부모 컴포넌트에서 props로 색상을 받아 버튼을 누르면 state.number 값이 1씩 증가한다.color 값을 state에 동기화하고 있으며, getSnapshotBeforeUpdate는 DOM에 변화가 일어나기 적진의 색상 속성을 snapshot 값으로 변환하여 이것을 componentDidUpdate에서 조회할 수 있다.state.number 값의 마지막 자리 수가 4(ex. 4, 14, 24, 34 등등)로 끝나면 리렌더링을 취소한다.src/App.js 파일에 다음과 같이 코드를 작성했다.//App.js
// 랜덤 색상 생성하는 함수
function getRandomColor() {
return '#' + Math.floor(Math.random() * 16777215).toString(16);
}
class App extends Component {
state = {
color: '#000000'
}
handleClick = () => {
this.setState({
color: getRandomColor()
});
}
render() {
return (
<div>
<button onClick={this.handleClick}>랜덤 색상</button>
<LifeCycleSample color={this.state.color}/>
</div>
);
}
}16777215는 hex 표현으로 ffffff이다.handleClidk 메서드가 호출되게 이벤트를 설정했고, 불러온 LifeCycleSample 컴포넌트에 color 값을 props로 설정한다.주의 ❗❗
LifeCycleSample.js에서<p>color: {this.state.color}</p>구문을<p>color: {this.props.color}</p>로 고쳤다.
* 나도 모르게 state 값을 받아왔는데props로color값을 받아왔던 점 주의하자.

2.3 에러 잡아내기
- 방금 만든
LifeCycleSample컴포넌트의render함수에서 에러가 발생할 경우 브라우저에 아무것도 출력되지 않는다. - 따라서 사용자들이 당황하지 않도록
src/ErrorBoundary.js라는 컴포넌트를 생성하여 아래의 코드를 작성했다.
class ErrorBoundary extends Component {
state = {
error: false
};
componentDidCatch(error, info) {
this.setState({
error: true
});
console.log({ error, info });
}
render() {
if(this.state.error) return <div>에러 발생</div>;
return this.props.children;
}
}
- 에러가 발생하면 componentDidCatch 메서드가 호출되어
this.state.error값을true로 업데이트한다. - 그 후,
render함수는this.state.error값이true라면 에러가 발생했음을 알려주는div 태그를 보여준다. - 사용 방법은
LifeCycleSample컴포넌트를 감싸주면 된다.
사용자에게 에러 출력 안되도록 주의✔
그리고 state와 props가 햇갈리는데 계속 반복해서 복습해야겠다. ㅠㅠ🤦♂️
end
Author And Source
이 문제에 관하여([React] 9. 라이프사이클 메서드), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@daekyeong/React-9.-라이프사이클-메서드저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)