01. 라이프 사이클이란?
- 1) 가상돔이란?
👉 DOM을 기억하시나요?
DOM은 html 단위 하나하나를 객체로 생각하는 모델입니다. 예를 들면, 'div'라는 객체는 텍스트 노드, 자식 노드 등등, 하위의 어떤 값을 가지고 있겠죠? 이런 구조를 트리 구조라고 합니다.
네, 맞습니다! DOM이 트리구조란 소리입니다.
- DOM 트리 중 하나가 수정될 때마다 모든 DOM을 뒤지고, 수정할 걸 찾고, 싹 수정을 한다면?
→ 필요없는 연산이 너무 많이 일어난다!
→ 그래서 등장한 게 가상돔!
- 가상돔은 메모리 상에서 돌아가는 가짜 DOM입니다.
- 가상돔의 동작 방식: **기존 DOM과 어떤 행동 후 새로 그린 DOM(가상 돔에 올라갔다고 표현합니다)을 비교해서 정말 바뀐 부분만 갈아끼워줍니다! → 돔 업데이트 처리가 정말 간결하죠!**
👉 어렵지 않죠! 그럼 어떤 행동을 해야 DOM을 새로 그릴까요?
- 처음 페이지 진입했을 때도 그리겠죠!
- 데이터가 변했을 때도 그릴 겁니다!
💡 알면 덜 찜찜한 이야기: **DOM이 정말 그렇게 느려?**
반은 맞고 반은 틀려요. DOM은 사이트 구조에 따라 가상돔을 쓰는 것보다 훨씬 성능이 좋을 수 있고(=빠를 수 있고), 속이 터지게 느릴 수 있습니다.
- 2) 라이프 사이클이란?
👉 컴포넌트의 라이프 사이클(= 컴포넌트 생명주기)은 정말 중요한 개념입니다!
**컴포넌트가 렌더링을 준비하는 순간부터, 페이지에서 사라질 때까지**가 라이프 사이클이에요.
[공식 문서](https://ko.reactjs.org/docs/state-and-lifecycle.html)에서도 자세히 다루고 있어요.
- 아래 도표는 어떻게 라이프 사이클이 흘러가는 지 그린 도표입니다.
([도표 보러가기](https://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/))
![https://s3-us-west-2.amazonaws.com/secure.notion-static.com/503b6fe9-9af4-4898-8cde-8d29b8085826/_2020-10-17__4.26.12.png](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/503b6fe9-9af4-4898-8cde-8d29b8085826/_2020-10-17__4.26.12.png)
- 컴포넌트는 생성되고 → 수정(업데이트)되고 → 사라집니다.
- 생성은 처음으로 컴포넌트를 불러오는 단계입니다.
- 수정(업데이트)는 사용자의 행동(클릭, 데이터 입력 등)으로 데이터가 바뀌거나, 부모 컴포넌트가 렌더링할 때 업데이트 됩니다. 아래의 경우죠!
- props가 바뀔 때
- state가 바뀔 때
- 부모 컴포넌트가 업데이트 되었을 때(=리렌더링했을 때)
- 또는, 강제로 업데이트 했을 경우! (forceUpdate()를 통해 강제로 컴포넌트를 업데이트할 수 있습니다.)
- 제거는 페이지를 이동하거나, 사용자의 행동(삭제 버튼 클릭 등)으로 인해 컴포넌트가 화면에서 사라지는 단계입니다.
02. 라이프 사이클 함수로 보는 라이프 사이클
👉 **라이프 사이클 함수는 클래스형 컴포넌트에서만 사용할 수 있습니다.**
라이프 사이클을 아는 건 중요한데 왜 우리는 클래스형 컴포넌트보다 함수형 컴포넌트를 많이 쓰냐구요?
리액트 공식 매뉴얼에서 **함수형 컴포넌트를 더 권장**하기 때문입니다!
(리액트 16.8버전부터 등장한 **React Hooks**으로 라이프 사이클 함수를 대체할 수 있거든요.)
더 많은 라이프 사이클 함수는 [공식 문서](https://ko.reactjs.org/docs/react-component.html)에서 확인할 수 있어요 😉
- [**코드스니펫] - 라이프 사이클 예제**
-
이 코드를 붙여넣고 콘솔 창에 어떤 순서로 찍히는 지 확인해봅시다!
라이프 사이클 함수가 어떤 순서로 움직이는 지 보면 이해하기 쉬울 거예요.
LifecycleEx.js 파일을 만들고 → 이 코드를 붙여넣기!
그리고 App.js에서 LifecycleEx 파일을 불러오는 거 잊지마세요! 저는 새 프로젝트를 만들어서 해볼게요.
import React from "react";
class LifecycleEx extends React.Component {
constructor(props) {
super(props);
this.state = {
cat_name: '나비',
};
console.log('in constructor!');
}
changeCatName = () => {
this.setState({cat_name: '바둑이'});
console.log('고양이 이름을 바꾼다!');
}
componentDidMount(){
console.log('in componentDidMount!');
}
componentDidUpdate(prevProps, prevState){
console.log(prevProps, prevState);
console.log('in componentDidUpdate!');
}
componentWillUnmount(){
console.log('in componentWillUnmount!');
}
render() {
console.log('in render!');
return (
<div>
{}
<h1>제 고양이 이름은 {this.state.cat_name}입니다.</h1>
<button onClick={this.changeCatName}>고양이 이름 바꾸기</button>
</div>
);
}
}
export default LifecycleEx;
- 3) constructor()
👉 생성자 함수라고도 부릅니다. 컴포넌트가 생성되면 가장 처음 호출되는 친구죠!
- 4) render()
👉 컴포넌트의 모양을 정의하는 친구입니다!
여기에서도 state, props에 접근해서 데이터를 보여줄 수 있어요.
리액트 요소를 return에 넣어 반환해줬던 거 기억하시죠?
render() 안에 들어갈 내용은 컴포넌트의 모양에만 관여하는 것이 가장 좋습니다.
즉, state나, props를 건드려 데이터를 수정하려고 하면 안됩니다!
- 5) componentDidMount()
👉 컴포넌트가 화면에 나타나는 것을 **마운트(Mount)한다**고 표현합니다. didMount()는 마운트가 완료 되었다는 소리겠죠?
이 함수는 첫번째 렌더링을 마친 후에만 딱 한 번 실행됩니다. 컴포넌트가 리렌더링할 때는 실행되지 않아요.
보통은 이 안에서 ajax 요청, 이벤트 등록, 함수 호출 등 작업을 처리합니다.
또, 이미 가상돔이 실제돔으로 올라간 후니까 DOM 관련 처리를 해도 됩니다!
- 6) componentDidUpdate(prevProps, prevState, snapshot)
👉 DidMount()가 첫 렌더링 후에 호출 되는 함수라면, DidUpdate()는 리렌더링을 완료한 후 실행되는 함수입니다.
이 함수에 중요한 파라미터가 2개 있는데, prevProps와 prevState입니다. 각각 업데이트 되기 전 props, state예요. 이전 데이터와 비교할 일이 있다면 가져다 쓰도록 합시다.
DidUpdate()가 실행될 때도 가상돔이 실제돔으로 올라간 후니까 DOM 관련 처리를 해도 됩니다!
- 7) componentWillUnmount()
👉 컴포넌트가 DOM에서 제거 될 때 실행하는 함수입니다.
만약 우리가 스크롤 위치를 추적 중이거나, 어떤 이벤트 리스너를 등록했다면 여기에서 꼭꼭 해제를 해줘야 합니다.
컴포넌트 없이 이벤트만 남겨둘 순 없잖아요!
🔥 componentWillUnmount()가 호출되는 걸 보려면, app.js에서 를 없애봐야겠죠?
삼항연산자를 사용해서 컴포넌트를 보여주거나, 없애는 걸 **조건부 렌더링**이라고 불러요.
**이건 저만 진행할게요! 눈으로만 따라와주기!**