React는 각 컴포넌트마다 고유의 생명주기(LifeCycle)을 가진다. class형 컴포넌트의 render
함수 전후로 각 생명주기 함수를 갖는다.
import React, { Component } from "react";
class Banner extends Component {
render() {
return <div>hello carrots</div>;
}
}
export default Banner;
Banner라는 컴포넌트가 있다 가정해보자. DOM에 그려지고 없어지기 까지 과정(Life Cycle)이 있고 React에선 각 생명주기에 대한 컨트롤을 위해 메소드를 제공한다. 각 메소드는 Class형 컴포넌트에서만 사용가능하며 다음과 같은 프로세스를 지닌다.
React에서 생명주기 메소드에 대해 설명할때 사용되는 다이어그램이다. 컴포넌트에서 최종적으로 호출하는 render
함수 전 후로 생명주기 별 메소드 실행 순서를 갖는다.
import React, { Component } from 'react';
export default class Basic extends Component {
constructor(props) {
super(props);
console.log("constructor");
}
componentDidMount() {
console.log('componentDidMount');
}
componentDidUpdate(prevProps, prevState) {
console.log('componentDidUpdate');
}
componentWillUnmount() {
console.log("componentWillUnmount");
}
render() {
return (
<div>
뭐 대강 이런식이라능
</div>
);
}
}
뭐 대충 이런구조인데 각 메소드별로 설명해보겠다.
👽 먼저 React 생명주기에는 세가지 경우가 존재한다.
예로 마운트란 디스크와 같은 물리장치의 특정위치를 연결시켜주는 것을 말한다. React의 마운트도 같은 개념이다. 각 컴포넌트를 위치에 맞게 연결시켜주는 절차를 마운트라고 하는데, 이것은 컴포넌트의 생성과 동시에 연결 작업이 이루어지기 떄문에 마운트 단계라고 칭한다.
1. constructor
말그대로 생성자 메소드다. 뭔 짓을 해도 얘가 먼저임
constructor(props) {
super(props); // super로 부모 컴포넌트의 생성자를 호출해줘야 this 키워드 사용가능
console.log("constructor");
}
2. getDerivedStateFromProps
getDerivedStateFromProps
는 props
로 받아온 것을 state
에 꽂아넣을 때 사용한다. return
타입으로 Javascript Object를 주어야 한다. return
된 Object는 state
에 반영된다.
💥 메소드 앞에 static
을 필요로 하고, 내부 this
키워드 사용 불가
static getDerivedStateFromProps(nextProps, prevState) {
console.log("getDerivedStateFromProps");
if (nextProps.color !== prevState.color) {
return { color: nextProps.color };
}
return null;
}
3. render
컴포넌트 렌더링시 호출되는 메소드다. 모든 클래스형 컴포넌트의 return
타입이다.
render() {
console.log('render');
return (
<div>
뭐 대강 이런식이라능
</div>
);
}
4. componentDidMount
컴포넌트의 첫번째 렌더링이 마치고 호출되는 메소드로, 호출되는 시점에는 페이지내 컴포넌트가 화면에 나타난 상태다. 여기선 주로 D3, masonry 처럼 DOM 을 사용해야하는 외부 라이브러리 연동을 하거나, 해당 컴포넌트에서 필요로하는 데이터 fetch를 위한 axios, DOM 속성을 읽어 변경 및 UI 작업이 이루어진다.
componentDidMount() {
console.log('componentDidMount');
}
React에서의 갱신의 개념은 props
, state
등 상태에 대한 갱신을 말한다. React는 모든 값에 대해 갱신 이벤트를 감지할 수 있으며, 이를 통해 모듈을 분리하고 결합하는 구조를 지닐 수 있다.
1. getDerivedStateFromProps
마운트의 getDerivedStateFromProps
메소드와 동일하다.
2. shouldComponentUpdate
shouldComponentUpdate
메소드는 컴포넌트가 리렌더링 할지 말지를 결정하는 메소드다. true/false
로 렌더링을 컨트롤하며, 주로 앱 최적화시 사용하는 메소드다. React.memo
와 동일한 기능이다. 이는 추후 포스트에서 다루겠다.
shouldComponentUpdate(nextProps, nextState) {
console.log("shouldComponentUpdate", nextProps, nextState);
// carrots이 아닌 경우 렌더링하지 않음
return nextState.userName == 'carrots';
}
3. render
마운트의 render
메소드와 동일하다.
4. getSnapshotBeforeUpdate
getSnapshotBeforeUpdate
는 Virtual DOM이 실제 DOM에 반영되기 직전에 실행된다. 이 메서드에선 이전과 현재의 props
와 state
를 접근가능하다. return
된 값은 이후 호출될 componentDidUpdate
3번째 인자로 전달된다.
getSnapshotBeforeUpdate(prevProps, prevState) {
console.log("getSnapshotBeforeUpdate");
if (prevProps.color !== this.props.color) {
return this.myRef.style.color;
}
return null;
}
5. componentDidUpdate
componentDidUpdate
는 DOM에 리렌더링 이후 변화가 모두 반영되고 난 뒤 호출되는 메소드로. 3번째 파라미터로 getSnapshotBeforeUpdate
에서 반환한 값을 조회할 수 있다.
componentDidUpdate(prevProps, prevState, snapshot) {
console.log("componentDidUpdate", prevProps, prevState);
if (snapshot) {
console.log("업데이트 되기 직전 색상 : ", snapshot);
}
}
언마운트는 말그대로 마운트의 반대, 컴포넌트의 연결해제, 즉 컴포넌트의 삭제를 의미한다. document.unload와 같은 이벤트라고 생각하면 쉽다.
1. ComponentWillUnMount
componentWillUnmount
는 DOM에서 컴포넌트가 지워질때 실행된다. $(window).unload
와 유사한 기능이다. 컴포넌트와 관련된 것들을 정리하는데 사용한다. 예를 들어 로그아웃시 주 구성 Component를 해제하기 전에 사용자 세부정보와 모든 인증 토큰을 지운다거나 setInterval
을 clear
한다거나 할 수 있다.
💥 ReactV16.3부터 will
이 포함된 메소드는 Deprecated됐으나, 컴포넌트 해제의 경우 componentDidUnmount
를 제공할 수 없다. 이미 제거된 컴포넌트에서 이벤트를 발생시킬 수 없기 때문이다.
componentWillUnmount() {
console.log("componentWillUnmount");
}
ReactV16.3 버전 이후로 Deprecated된 메소드가 존재한다.
will
메소드가 Deprecated된 이유 > reactjs.org/blog
요약하자면 React 커뮤니티에서 가장 혼란을 가져오는 LifeCycle기 때문에 없앴다고 한다. 보통 DOM에 대한 제어가 끝난 뒤에 데이터 fetch등이 이루어지는 것이 일반적이다. 그러나 렌더링 직전에 데이터 조회 및 state 변경시 하위 모듈에 끼치는 영향에 대해 추적이 힘든 것이 주된 이유인 것 같다.
👽 그래도 죽어도 써야겠으면 ReactV17부터는 UNSAFE_
라는 Prefix를 붙여서 사용해야된다. 어구에서 보다 싶이 불안정하니 쓰지말라는 듯하다. 쓰지말라면 걍 쓰지 말자;;
UNSAFE_componentWillMount() {
console.log('UNSAFE_componentWillMount');
}
UNSAFE_componentWillreceiveProps(nextProps) {
console.log('UNSAFE_componentWillreceiveProps', nextProps);
}
UNSAFE_componentWillupdate(nextProps, nextState) {
console.log('UNSAFE_componentWillupdate', nextProps, nextState);
}
오늘은 React의 컴포넌트 생명주기 메소드, 그중 class형 컴포넌트용 메소드에 대해 알아봤다. Jquery가 만연하던 시절, $(document).ready는 거의 모든 페이지에 필수적으로 사용되었다는 것을 알 것이다. 프론트엔드 개발에 있어 특정 페이지에 대한 생명주기 컨트롤은 그만큼 중요하고 사용빈도가 높다. 그만큼 이해를 정확히 하고 넘어가야 한다고 느낀다.
오늘 저녁은 삼겹볶음이다. 🥕
참고 : https://www.paduckk-dev.com/development/React%20LifeCycle/
https://medium.com/@changmoomoon/react-v16-3-%EC%9D%B4%ED%9B%84-lifecycle-api-%EC%B4%9D-%EC%A0%95%EB%A6%AC-16-3v%EB%B6%80%ED%84%B0-deprecated%EB%90%9C-api%EB%8F%84-%ED%8F%AC%ED%95%A8-37456f843efd
https://react.vlpt.us/basic/25-lifecycle.html
https://velog.io/@st2702/React-Lifecycle-%EC%83%9D%EB%AA%85%EC%A3%BC%EA%B8%B0