React를 사용할 때는 컴포넌트를 class 또는 함수로 정의할수 있습니다. 그리고 컴포넌트는 여러 종류의 생명주기 메소드를 가지며 이 메서드를 오버라이딩하여 특성 시점에 코드가 실행되도록 설정할 수 있습니다. 이를 Life Cycle Event
라고 합니다.
각 단계에서 실행되는 메소드들에 대해 알아보겠습니다.
컴포넌트가 처음 실행될 때를 Mount
라고 표현합니다.
우리가 만든 컴포넌트가 브라우저에 나타날 때 가장 먼저 실행되는 함수입니다. 단 한번만 실행되며, constructor내부에서 선언된 setState는 무시되는 특징을 가지고 있습니다.
constructor(props) {
super(props);
console.log('constructor');
}
컴포넌트 렌더링을 해줍니다.
컴포넌트가 만들어지고 render가 호출된 후에 실행이되는 메소드입니다.
- 컴포넌트에서 필요한 데이터 요청 : Ajax, GraphQL, etc
- DOM에서 관련된 작업 : 스크롤 설정, 크기 읽어오기 등
- 외부 라이브러리 연동
- 정적 메소드이기 때문에 this 객체에 접근할 수 없다.
- 컴포넌트가 브라우저에 보여질 때, 어떠한 작업을 하겠다는 메소드
componentDidMount() {
console.log('componentDidMount');
}
v16.3
부터는 componentWillReceiveProps
API는 사용되지않고 getDerivedStateFromsProps
가 생겼습니다. props값과 state값을 동결시킬 때 사용합니다.
//MyComponent.js
import React, { Component } from "react";
class MyComponent extends Component {
state = {
value: 0,
};
static getDerivedStateFromProps(nextProps, prevState) {
if (prevState.value !== nextProps.value) {
return {
value: nextProps.value,
};
}
return null;
}
render() {
return (
<div>
<p>props: {this.props.value}</p>
<p>state: {this.state.value}</p>
</div>
);
}
}
export default MyComponent;
//App.js
import React, { Component } from 'react';
import MyComponent from 'Mycomponent';
class App extends Component {
state = {
counter: 1
}
constructor(props) {
super(props);
}
handleClick = () => {
this.setState({
counter: this.state.counter + 1
});
}
render() {
return (
<div>
<MyComponent value={this.state.counter}/>
<button onClick={this.handleClick}>Click Me</button>
</div>
);
}
}
위 코드 실행 시, button을 클릭하면 props의 값이 바뀜에 따라 state의 값도 바뀌면서 1씩 증가합니다.
sholudComponentUpdate
는 업데이트를 막아준다고 생각하면 됩니다. 특정 조건에 따라 렌더링을 막아줍니다.
//MyComponent.js
import React, { Component } from "react";
class MyComponent extends Component {
state = {
value: 0,
};
static getDerivedStateFromProps(nextProps, prevState) {
if (prevState.value !== nextProps.value) {
return {
value: nextProps.value,
};
}
return null;
}
//추가 된 부분
shouldComponentUpdate(nextProps, nextState) {
if (nextProps.value === 10) return false;
return true;
}
render() {
return (
<div>
<p>props: {this.props.value}</p>
<p>state: {this.state.value}</p>
</div>
);
}
}
export default MyComponent;
조건문에 의해 props의 값이 10되면 화면에서 렌더링이 되지 않습니다(화면에 아무것도 표현해주지 않습니다).
DOM 변화가 일어나기 직전의 DOM 상태를 가져와줍니다. 이 부분은 예시를 통해 쉽게 이해하겠습니다.
특정 props의 값이 바뀌면 특정한 작업을 할 수 있게 해줍니다. API호출은 this 객체가 필요한 경우가 많기 때문에 componentDidUpdate
메소드에서 처리가능합니다. 이전의 props값과 현재의 값이 바뀌면 console에 메세지를 띄우는 예시입니다.
//MyComponent.js
import React, { Component } from "react";
class MyComponent extends Component {
state = {
value: 0,
};
static getDerivedStateFromProps(nextProps, prevState) {
if (prevState.value !== nextProps.value) {
return {
value: nextProps.value,
};
}
return null;
}
shouldComponentUpdate(nextProps, nextState) {
if (nextProps.value === 10) return false;
return true;
}
//추가된 부분
componentDidUpdate(preProps, prevState) {
if(this.props.value !== prevProps.value){
console.log('value 값이 바뀌었습니다.', this.props.value);
}
}
render() {
return (
<div>
<p>props: {this.props.value}</p>
<p>state: {this.state.value}</p>
</div>
);
}
}
export default MyComponent;
특정 조건이 되면 컴포넌트를 없애주는 함수입니다. 값이 10되면 MyComponent컴포넌트가 사라지게되는 예제입니다.
//App.js
import React, { Component } from 'react';
import MyComponent from 'Mycomponent';
class App extends Component {
state = {
counter: 1
}
constructor(props) {
super(props);
}
handleClick = () => {
this.setState({
counter: this.state.counter + 1
});
}
render() {
return (
<div>
{this.state.counter < 10 && < MyComponent value={this.state.counter}/>}
<button onClick={this.handleClick}>Click Me</button>
</div>
);
}
}
//MyComponent.js
import React, { Component } from "react";
class MyComponent extends Component {
state = {
value: 0,
};
static getDerivedStateFromProps(nextProps, prevState) {
if (prevState.value !== nextProps.value) {
return {
value: nextProps.value,
};
}
return null;
}
shouldComponentUpdate(nextProps, nextState) {
if (nextProps.value === 10) return false;
return true;
}
componentDidUpdate(preProps, prevState) {
if(this.props.value !== prevProps.value){
console.log('value 값이 바뀌었습니다.', this.props.value);
}
}
//추가된 부분
componentWillUnmount() {
console.log('ByeBye');
}
render() {
return (
<div>
<p>props: {this.props.value}</p>
<p>state: {this.state.value}</p>
</div>
);
}
}
export default MyComponent;
render()에서 에러가 날 경우 처리해줄 수 있는 함수입니다. 예를 들면 게임을 하다가 에러로 인해 비정상적으로 종료가 되었을 시 아래와 같은 메세지를 본 적이 있을 것입니다. 이 때, 보고를 누른다면 개발자에게 에러에 대한 정보가 전송되고 개발자는 실수로 잡지 못했던 에러를 잡을 수 있습니다. 중요한 점은 에러가 발생할 수 있는 컴포넌트의 부모 컴포넌트에서 사용할 수 있다는 것입니다.