라이프 사이클 함수
라이프 사이클?
모든 리액트 컴포넌트에는 라이프 사이클(수명 주기)이 존재합니다. 라이프 사이클은 컴포넌트가 생성되고 소멸될 때까지 일련의 과정을 의미 합니다.
라이프 사이클 함수
총 10가지의 함수가 존재하며, will이 붙은 함수는 어떤 작업을 하기 전에 실행되고, did가 붙은 함수는 작업을 한 후에 실행됩니다.
라이프 사이클 함수를 사용 하는 경우
어떤 작업을 수행할 때 렌더링 할 때 처리해야 하는 경우가 있고 업데이트 전후로 처리해야 하는 경우가 있는데 이럴 경우 라이프 사이클 함수를 이용해서 처리합니다.
컴포넌트의 라이프 사이클
마운트(페이지에 컴포넌트가 나타남) -> 업데이트(리렌더링) -> 언마운트(페이지에서 컴포넌트가 사라짐)
마운트?
DOM이 생성되고 웹 브라우저상에 나타는 과정
업데이트?
컴포넌트를 업데이트 하는 경우로 아래와 같은 경우에 동작합니다.
1) Props가 바뀔 경우
2) state가 바뀔 경우
3) 부모 컴포넌트가 리렌더링 할 경우
4) this.forceUpdate로 강제로 렌더링을 트리거 할 경우
언마운트?
마운트의 반대 과정으로 DOM에서 컴포넌트를 제거하는 과정
관련 함수
1) render()
컴포넌트 모양새를 정의
이 함수 안에서 this.props, this.state에 접근
리액트 요소를 반환, 아무것도 보여주지 않는다면 null이나 false를 반환
state를 변형하면 안되고 웹 브라우저에 접근해서도 안됨 => DOM 정보를 가져오거나 변화를 줄 떄에는 componentDidMount에서 처리해야 함
2) Constructor()
Constructor(props) {...}
컴포넌트를 처음 만들 때 사용
초기 state설정
3) getDerivedStateFormProps()
리액트 v16.3 이후에 새로 만든 라이프사이클 함수
props로 받아온 값을 state에 동기화 시키는 용도로 사용
컴포넌트를 마운트하거나 props를 변경할 때 호출
4) componentDidMount()
componentDidMount(){...}
컴포넌트를 만들고 첫 렌더링을 마친 후 실행
다른 자바스크립트 라이브러리나 프레임워크의 함수 호출, 이벤트 등록, setTimeout, setInterval, 네트워크 요청 등 비동기 작업 처리
5) shouldComponentUpdate()
shouldComponentUpdate(nextProps, nextState) {...}
props또는 state 변경 시 리렌더링을 시작할지 여부를 지정하는 함수
반드시 true & false 반환 해야함
현재 props, state 변경은 this키워드를 붙이고 새로 설정할 props, state는 nextProps, nextState로 접근
6) getSnapshotBeforeUpdate()
v16.3 이후 만든 메소드
ender 메소드를 호출한 후 DOM에 변화를 반영하기 바로 직전에 호출하는 함수
componentDidUpdate에서 세번 째 파라미터인 snapshot 값으로 전달 받을 수 있는데 주로 업데이트 하기 직전의 값을 참고할일이 있을 때
7) componentDidUpdate()
componentDidUpdate(prevProps, prevState, snapshot) {...}
prevProps, prevState 사용하여 이전에 가졌던 데이터에 접근
getSnapshotBeforeUpdate에서 반환한 값이 있다면 여기서 snapshot 값을 전달 받을 수 있음
8) componentWillUnmount()
componentWillUnmount(){...}
DOM에서 제거할 때 실행
componentDidMount에서 등록한 이벤트, 타이머, 직접 생성한 DOM이 있다면 여기에서 제거 작업
예제
아래 예제는 함수가 언제 동작하는 지 확인해보기 위해 작성한 예제입니다.
색을 랜덤으로 업데이트 하는 버튼과 숫자를 올려주는 버튼 두개로 구성됩니다.
숫자가 4로 끝날 경우에만 리렌더링 되지않고, 나머지 숫자일 때에는 업데이트가 발생하면 리렌더링 됩니다.
LifeCylce.js
import React, { Component } from 'react';
class LifeCycle extends Component {
state ={
number : 0,
color : null
}
myRef = null;
constructor(props){
super(props);
console.log('constructor()');
}
static getDerivedStateFromProps(nextPorps, prevState){
if(nextPorps.color !== prevState.color){
return {
color:nextPorps.color
};
}
return null;
}
componentDidMount(){
console.log('componentDidMount()');
}
shouldComponentUpdate(nextPorps, nextState){
console.log("shouldComponentUpdate(),", nextPorps,",", nextState);
return nextState.number %10 !==4;
}
componentWillUnmount(){
console.log("componentWillUnmount()");
}
handleClick = () =>{
this.setState({
number : this.state.number +1
});
}
getSnapshotBeforeUpdate(prevProps, prevState){
console.log('getDerivedStateFromProps()');
if(prevProps.color !== this.props.color){
return this.myRef.style.color;
}
return null;
}
componentDidUpdate(prevProps, prevState, snapshot){
console.log('componentDidUpdate()');
if(snapshot){
console.log('업데이트 되기 직전 색상 : ',snapshot);
}
}
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}>plus</button>
</div>
);
}
}
export default LifeCycle;
app.js
import React, { Component } from 'react';
import './App.css';
import LifeCycle from './component/LifeCycle';
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}>Random Color</button>
<LifeCycle color={this.state.color}/>
</div>
);
}
}
export default App;
동작결과
처음 렌더링 된 후 찍힌 결과입니다. 생성자 함수, getDerivedStateFromProps함수, render함수 componentDidMount 함수가 차례대로 실행 됩니다.
초기 렌더링 후 화면입니다.
랜덤 버튼과 플러스 버튼을 클릭했을 때의 결과 입니다. 숫자가 4로 끝나는 경우에만 리 렌더링 되지않고 나머지의 경우에는 리 렌더링 됩니다.
랜덤버튼 클릭
플러스 버튼 클릭
두 버튼을 클릭했을 때 바뀌는 화면입니다.
참고 : 리액트를 다루는 기술(저:VELOPERT)