생애주기 카테고리
1. 마운트
2. 업데이트
3. 언마운트
라이프사이클 메서드
총 9개의 메서드로 구성
Will : 어떤 작업을 하기 전에 실행되는 메서드
Did : 어떤 작업을 완료한 후에 실행되는 메서드
마운트
Dom이 생성되고, 웹브라우저상에 처음 나타나는 것
과정
- 컴포넌트 생성
- constructor 실행
- getDerivedStateFromProps
부모로 부터 받은 props를 자신이 가진 state에 넣을때 사용하는 메서드 - render
- componentDidMount
업데이팅
업데이팅은 다음의 네 경우에서 일어남
- props가 바뀔때
- state가 바뀔때
- 부모 컴포넌트가 리렌더링될때
- this.forceUpdate로 강제 렌더링을 트리거할때
과정
- 업데이트 trigger
- getDerivedStateFromProps
부모로 부터 받은 props를 state로 관리 - shoudComponentUpdate
컴포넌트가 업데이트 되어야 하는지 -> 부모컴포넌트만 변경되고 자식은 그대로이면 바뀔 필요가 없으므로 필요함
true 또는 false를 반환해야함
false인경우 render가 발생하지 않음 - render
- getSnapShotBeforeUpdate
- componentDidUpdate
언마운트
마운트의 반대과정
컴포넌트를 DOM에서 제거하는 것
componentWillUnmount : 컴퍼넌트가 사라지기 전에 호출하는 메서드
실제 코드로 확인하기
아래와 같이 Component 를 상속하고, 메서드를 오버라이딩하여 생애주기를 눈으로 확인할 수 있다.
LifeCycleSample.js
import { Component } from 'react';
export default class LifeCycleSample extends Component {
state = {
number: 0,
color: null,
};
myRef = null;
constructor(props) {
super(props);
console.log('constructor');
}
static getDerivedStateFromProps(nextProps, prevState) {
console.log(
'===========================getDerivedStateFromProps========================='
);
console.log('부모로부터 받은 props', nextProps);
console.log('이 컴포넌트의 이전 state', prevState);
if (nextProps.color !== prevState.color) {
console.log('이전 state와 부모로 부터 받은 props가 달라 state를 변경함');
console.log(
'===========================getDerivedStateFromProps========================='
);
return { color: nextProps.color };
}
console.log('===========================================================');
return null;
}
componentDidMount() {
console.log('컴포넌트 마운트 완료!');
console.log('===========================================================');
}
shouldComponentUpdate(nextProps, nextState) {
console.log('shouldComponentUpdate');
console.log('다음 state', nextState);
console.log('다음 props', nextProps);
console.log('===========================================================');
return nextState.number % 10 !== 4;
}
componentWillUnmount() {
console.log('언마운트되기 직전!');
}
handleClick = () => {
this.setState({
number: this.state.number + 1,
});
};
getSnapshotBeforeUpdate(prevProps, prevState) {
console.log('getSnapshotBeforeUpdate');
if (prevProps.color !== this.props.color) {
return this.myRef.style.color;
}
return null;
}
componentDidUpdate(prevProps, prevState, snapshot) {
console.log('컴포넌트 업데이트 완료!');
console.log('componentDidUpdate', prevState, prevProps);
if (snapshot) {
console.log('업데이트 이전 색상 :', snapshot);
}
console.log('===========================================================');
}
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.state.color}</p>
<button onClick={this.handleClick}>더하기</button>
</div>
);
}
}
App.js
import { Component } from 'react';
import LifeCycleSample from './component/classComponent';
function getRandomColor() {
return '#' + Math.floor(Math.random() * 16777215).toString(16);
}
class App extends Component {
state = {
color: '#000000',
canSee: true,
};
handleClick = () => {
this.setState({
color: getRandomColor(),
});
};
handleShadow = () => {
this.setState({
canSee: !this.state.canSee,
});
};
render() {
return (
<div>
<button onClick={this.handleClick}>랜덤색상</button>
{this.state.canSee && (
<LifeCycleSample color={this.state.color}></LifeCycleSample>
)}
<button onClick={this.handleShadow}>숨기기</button>
</div>
);
}
}
export default App;
현재 이 코드의 App에서 LifeCycle으로 props를 통해 color를 내려주는 상황이다.
마운트단계
컴포넌트 클래스의 constructor가 실행되고, getDerivedStateFromProps를 통해 부모로 부터 받은 props(color)와 자신의 state를 비교하여 state를 변경한뒤, render하는 것을 확인할 수 있다.
업데이트
state가 변경되는 경우
더하기를 통해 LifeCycle의 state를 변경했다.
getDerivedStateFromProps를 통해 props와 state를 비교한다. 이때 props의 color와 state의 color가 동일하므로 변경하지 않는다.
shouldComponentUpdate에서 정말 리렌더링을 할 것인지 여부를 판단한다. 업데이트될 state와 props를 확인할 수 있다.
getSnapShotBeforeUpdate가 호출되고, 이후 componentDidUpdate가 호출되어, 컴포넌트 업데이트가 끝난 모습이다.
props가 변경되는 경우
마찬가지로 똑같은 과정을 거치나
getDerivedStateFromProps에서 부모 props가 변경되었으므로 state를 바꿔주는 모습을 확인할 수 있다.
언마운트
숨기기를 통해 canSee를 변경했고, 언마운트 되기 직전에 componentWillUnmount가 호출되는 것을 확인할 수 있다.