모든 리액트의 컴포넌트는 생명 주기가 존재한다. 컴포넌트의 수명은 처음 페이지에 랜더링 되기 전, 준비단계부터 페이지가 사라질 떄 끝나게 된다.
컴포넌트를 처음으로 랜더힐 할떄, 컴포넌트를 업데이트 하기 전후로 등등,
리액트에는 컴포넌트의 라이프 사이클이 있고, 그 사이클 동안, 컴포넌트를 관리하고, 수정할 수 있다.
라이프 사이클은 크게 3가지로 구분된다.
Mounting(마운팅)
DOM이 생성되고 웹 브라우저에 나타나는 것을 Mounting(마운팅)이라고 부른다.
이떄 총 4개의 빌트-인 메서드가 호출될 수 있다.
1.constructor()
2.getDerivedStateFormProps()
3.render()
4.componentDIdMount()
3번쨰 render()메서드는 필수적이고, 나머지는 직접 정의를 한다면 사용가능하다(선택적)
이제 마운팅의 메서드에 대해 하나하나 살펴보자.
constructor
React컴포넌트의 생성자(constructor)는 해당 컴포넌트가 마운팅 되기 전에 생성된다.
constructor를 구현할 떄 super(props)를 반드시 호출해야 한다.
-> 그렇지 않으면 this.props가 정의되지 않아 오류 발생 가능
React에서 constructor는 크게 2가지 목적이 있다.
-this.state로 state초기화
-인스턴스에 이벤트 처리 메서드 바인딩
-state를 초기화 하는 코드-
constructor(props){
super(props);
this.state = {
name:'이름'
}
}
-인트선트에 이벤트 처리 메서드 바인딩하는 코드-
constructor(props){
super(props);
this.handlechange = this.handlechange.bind(this);
this.handleclick = this.handleclick.bind(this);
this.handpress = this.handpress.bind(this);
this.divRef = React.createRef();
this.handleFocus = this.handleFocus.bind(this);
}
static getDerivedStateFormprops()
기본적으로 props에 있는 값을 state에 넣을 떄 사용하는 메서드이다.
마찬가지로 DOM이 생성되기 바로 직전,또는 갱신 시 render 메서드의 직전 에 호출된다.
state를 갱신하기 위한 객체를 반환하거나 null을 반환하여 갱신을 하지 않을 수 있다.
다음의 코드를 보자.
import React from 'react';
import ReactDOM from 'react-dom/client';
class Header extends React.Component {
constructor(props) {
super(props);
this.state = {favoritecolor: "red"};
}
static getDerivedStateFromProps(props, state) {
return {favoritecolor: props.favcol };
}
render() {
return (
<h1>My Favorite Color is {this.state.favoritecolor}</h1>
);
}
}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Header favcol="yellow"/>);
먼저 state에 favorutecolor:red로 설정이 되어있다.
하지만, props의 값을 state에 넣고 싶을 떄 getDerivedStateFromProps메서드를 사용한다.
getDerivedStateFromProps(props, state)에서 state의 값을 props로 바꿔주었다.
-자식 컴포넌트-
import React, { Component } from "react";
import { ReactDOM } from "react";
class HEAD extends Component{
constructor(props){
super(props);
this.state = {
color:'red'
};
}
static getDerivedStateFromProps(props,state){
return {color:props.value};
};
render(){
return(
<h1>MY Favorite color is {this.state.color}</h1>
);
}
}
export default HEAD;
먼저 이렇게 class component를 만들고, state에 color를 기본값으로 문자열 'red'로 지정해주었다.
그리고 바로 다음에 getDerivedStateFromProps메서드를 사용해 state의 값을 props.value로 바꿔준다.
-부모 컴포넌트-
import './App.css';
import { Component, createRef } from 'react';
import Example from './scroll';
import { render } from '@testing-library/react';
import itersample from './map';
import HEAD from './Counter';
class App extends Component{
render(){
return (
<HEAD value = 'green'></HEAD>
);
}
}
export default App;
state의 color가 red->props의 value인 green으로 바뀐 것을 볼 수 있다.
그러나 사용이 권장되는 메서드는 아니다
state를 끌고오면 코드가 장황해지고, 컴포넌트를 이해하기 힘들어 질 수 있다.
그래서 다른 대안을 사용한다
- props 변화에 대응한 부수 효과를 발생시켜야 한다면 (예를 들어, 데이터 가져오기 또는 애니메이션), componentDidUpdate 생명주기를 대신해서 사용하세요.
- props가 변화했을 때에만 일부 데이터를 다시 계산 하고 싶다면, Memoization Helper를 대신해서 사용하세요.
- props가 변화할 때에 일부 state를 재설정 하고 싶다면, 완전 제어 컴포넌트 또는 key를 사용하는 완전 비제어 컴포넌트로 만들어서 사용하세요.
- https://ko.reactjs.org/docs/react-component.html#static-getderivedstatefromprops
render
라이프 사이클 메서드 중 유일한 필수 메서드이다.
이 메서드 안에서 this.props, this.state에 접근할 수 있고, 리액트 요소를 반환한다.
<div>같은 태그가 반환 대상이 될 수 있고, 다른 컴포넌트도 반환 대상이 될 수 있다.아무것도 보여주기 싫다면 null이나 false를 반환한다.
render()함수는 순수해야 한다. 컴포넌트의 state를 변경 할 수 없으며,
만약 브라우저와 상호작용하고 싶으면 componentDidMount() 메서드를 사용하자.
componentDidMount
componentDidMount메서드는 컴포넌트가 마운트 된 직후, 컴포넌트가 첫 랜더링이 끝나면 실행된다.
이 안에서 다른 자바스크립트 라이브러리나 프레임워크의 함수를 호출하거나, setTimeout,setInterval 등 비동기 작업을 수행한다.
-자식 컴포넌트-
import { Component } from "react";
class Timer extends Component{
constructor(props){
super(props)
this.state = {
time:new Date()
}
};
componentDidMount(){
this.tick();
}
tick = () =>{
this.setState({
time:new Date()
})
};
render(){
const {time} = this.state
return(
<div>
{time.toLocaleTimeString()}
</div>
)
}
};
export default Timer;
-부모 컴포넌트-
import './App.css';
import { Component, createRef } from 'react';
import Example from './scroll';
import { render } from '@testing-library/react';
import itersample from './map';
import HEAD from './Counter';
import Timer from './tick';
class App extends Component{
render(){
return (
<Timer></Timer>
);
}
}
export default App;
페이지를 새로고침(랜더링) 할때마다 값이 갱신되는 것을 볼 수 있다.
즉 -> componentDidMount()는 랜더링 이후 즉시 호출되는 함수이다
Updating(업데이트)
컴포넌트가 업데이트 될때의 상태를 의미한다.
컴포넌트가 업데이트 된다는 것은, state, props, 부모 컴포넌트가 변경될 떄를 의미한다.
이떄, 5개의 메서드가 호출될 수 있다.
1.getDerivedStateFromProps()
2.shouldComponentUpdate()
3.render()
4.getSnapshotBeforeUpdate()
5.componentDidUpdate()
위의 getDerivedStateFormProps메서드는 위에 있으므로, 2번째 메서드 부터 살펴보자면,
shouldComponentUpdate()
부모 컴포넌트에서 다시 랜더링을 해도, (상태가 변경되어도) 그 자식컴포넌트가 영향을 받지 않는다면,
자식 컴포넌트는 불필요한 랜더링 과정을 거치게 된다.
이럴 떄 사용하는 것이 shouldComponentUpdate() 메서드이고, shouldComponent()는
리액트가 랜더링을 계속 해야할지, 아니면 랜더링을 하지 말아야 할지에 대한 Boolean값을 반환한다.
(기본 값은 true)
getSanpshotBeforeUpdate()
이 메서드는 리액트 V 16.3 이후 만든 메서드다.
이 메서드는 render에서 만들어진 결과물이 브라우저에 실제로 반영되기 직전에 호출된다.