라이프사이클 메서드(Lifecycle)
모든 리액트 컴포넌트에는 라이플사이클(수명주기)가 존재한다. 컴포넌트의 수명은 페이지에 랜더링 되기 전인 준비과정에서 시작하여 페이지에서 사라질 때 끝난다.
종류는 총 9가지.
- 'Will' : 작업을 작동하기 전, 'Did' : 작업을 작동한 후
그리고 3개의 카테고리로 나뉘는데
- 마운트 : 페이지에 컴포넌트가 나타남
- 업데이트 : 컴포넌트 정보를 업데이트
- 언마운트 : 페이지에서 컴포넌트가 사라짐
마운트
DOM이 생성되고 웹 브라우저상에 나타나는 것을 마운트(mount)라 한다.
호출되는 메서드
- counstructor : 컴포넌트는 새로 만들때 마다 호출되는 클래스 생성자 메서드
- getDerivedStateFromProps : props에 있는 값을 state에 넣을 때 사용하는 메서드
- render : 우리가 준비한 UI를 렌더링하는 메서드
- componentDidMount : 컴포넌트가 웹 브라우저상에 나타난 후 호출하는 메서드
업데이트
4가지 경우에 업데이트를 한다.
- props가 바뀔 때
- state가 바뀔 때
- 부모 컴포넌트가 리렌더링될 때
- this. forceUpdate로 강제로 렌더링 트리거할 때
호출되는 메서드
- getDerivedStateFromProps : props에 있는 값을 state에 넣을 때 사용하는 메서드
- shouldComponentUpdate: 컴포넌트가 리렌더링을 해야 할지 말아야 할지를 결정하는 메서드.
true 혹은 false 값을 반환하며 false를 반환하면 작업 중지. - render : 컴포넌트를 리렌더링
- getSnapshotBeforeUpdate : 컴포넌트 변화를 DOM에 반영하기 바로 직전에 호출하는 메서드
- componentDidUpdate : 컴포넌트의 업데이트 작업이 끝난 후 호출되는 메서드
언마운트
마운트의 반대 과정으로 컴포넌트를 DOM에서 제거하는 것을 의미
호출되는 메서드
- componentWillUnmount : 컴포넌트가 웹 브라우저상에서 사라지기전에 호출 되는 메서드.
라이프사이클 메서드
- render() : 컴포넌트의 모양새를 정의. 라이프사이클 메서드 중에서 유일하게 필수 메서드.
- consructor : 컴포넌트의 생성자 메서드로 컴포넌트 만들 때 처음으로 실행됨. 이 메서드에서는 초기 state를 정할 수 있다.
- getDerivedStateFromProps : props로 받아온 값을 state에 동기화. 마운트,업데이트 될 때 호출.
static getDerivedStateFromProps(nextProps, prevState) {
if(nextProps.value !== prevState.value) { // 조건에 따라 특정 값 동기화
return { value: nexProps.value };
}
return null; //state를 변경할 필요 없으면 null
}
- componentDidMount : 컴포넌트를 만들고 첫 렌더링을 마친 후 실행.
- shouldComponentUpdate : props,state가 변경됐을때, 컴포넌트가 리렌더링을 해야 할지 말아야 할지를 결정하는 메서드. true 혹은 false를 반환해야 함. 따로 생성하지 않으면 기본적으로 true 반환.
- getSnapshotBeforeUpdate : render에서 만들어진 결과물이 브라우저에 실제로 반영되기 직전에 호출됨. 주로 업데이트하기 직전의 값을 참고할 일이 있을때 활용됨(예: 스크롤바 위치 유지)
getSnapshotBeforeUpdate(prevProps, prevState) {
if(prevState.array !== this.state.array) {
const { scrollTop, scrollHeight } = this.list
return { scrollTop, scrollHeight };
}
}
- componentDidUpdate : 리렌더링을 완료한 후 실행. prevProps 또는 prevState를 사용하요 컴포넌트가 이전에 가졌던 데이터에 접근가능.
- componentWillUnmount : 컴포넌트를 DOM에서 제거시 사용.
- componentDidCatch : 렌더링 도중에 에러 발생시 먹통이 되지 않고 오류UI를 보여줌.
componentDidCatch(error, info) {
this.setState({
error: true
});
console.log({error, info});
}
라이프사이클 예제
// LifeCycleSample.js
import { thisExpression } from '@babel/types';
import React, { Component } from 'react';
class LifeCycleSample extends Component {
state = {
number: 0,
color: null,
}
myRef = null; //ref를 설정할 부분
constructor(props) {
super(props);
console.log('constructor');
}
static getDerivedStateFromProps(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.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('componentDidUpdate', prevProps, prevState);
if (snapshot) {
console.log('업데이트되기 직전 색 : ', snapshot);
}
}
render() {
console.log('render');
const style = {
color: this.props.color
};
return (
<div>
<h2>라이프사이클</h2>
{/* {this.props.missing.value} */} // 에러 생성
<h3 style={style} ref={ref => this.myRef = ref}>
{this.state.number}
</h3>
<p>color: {this.state.color}</p>
<button onClick={this.handleClick}>
더하기
</button>
</div>
)
}
}
export default LifeCycleSample;
// ErrorBoundary.js. 에러잡기
import React, { Component } from 'react';
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;
}
}
export default ErrorBoundary;
// App.js
import React, { Component } from 'react';
import LifeCycleSample from './LifeCycleSample';
import ErrorBoundary from './ErrorBoundary';
// 랜덤 색상 생성
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>
<div style={{ margin: '10px 0 0 50px' }}>
<button onClick={this.handleClick}>랜덤 색상</button>
<ErrorBoundary>
<LifeCycleSample color={this.state.color} />
</ErrorBoundary>
</div>
</div>
)
}
}
export default App;
'React' 카테고리의 다른 글
Context API (0) | 2021.08.05 |
---|---|
Hooks (0) | 2021.07.20 |
컴포넌트 반복 (0) | 2021.07.16 |
ref:DOM(클래스형컴포넌트) (0) | 2021.07.15 |
이벤트 핸들링 (0) | 2021.07.14 |
댓글