서론
이번 글의 내용은 나도 이해를 잘 못한 부분이라 설명이 난해할 수 있다.
라이프사이클이란 생명주기를 뜻하는데, 쉽게 말하면 컴포넌트가 렌더링되고 삭제되는 과정을 뜻한다.
참고로 이때까지 만든 컴포넌트들은 라이프사이클이 없는 컴포넌트들이었다...
무튼 만들어보자!
클래스형으론 어떻게 만들까?
클래스형으로 만들 때에는 componentWillMount -> render -> componentDidMount - > componentWillUnmount 메서드들이 이러한 순서를 가진다.
* mount : 어떤 컴포넌트가 생성된다. = 화면에 그려지다.
componentWillMount라는 메서드를 구현해서 그 안에 필요한 코드를 가져다 놓는 식으로 마운트되기 직전에,
즉 render 메서드가 호출되기 전에 해야 할 일을 수행할 수 있다.
var classStyle = 'color:red'; // class 바깥에
UNSAFE_componentWillMount() {
console.log('%cclass => componentWillMount', classStyle);
}
componentDidMount() {
console.log('%cclass => componentDidMount', classStyle);
}
shouldComponentUpdate(nevtProps, nextState) {
console.log('%cclass => shouldComponentUpdate', classStyle);
return true;
}
UNSAFE_componentWillUpdate(nevtProps, nextState) {
console.log('%cclass => componentDidUpdate', classStyle);
}
componentDidUpdate(nevtProps, nextState) {
console.log('%cclass => componentDidUpdate', classStyle);
}
저번 글에서 만들었던 ClassComp 컴포넌트 render 함수 바깥에 이 코드를 적어보자.
componentWillMount, componentWillUpdate는 리액트 17 버전 이상부터는 사용할 수 없어 앞에 UNSAFE_를 붙여줘야한다.
이대로 실행해보면 콘솔창에 componentWillMount -> render -> componentDidMount 이 순으로 출력되는 걸 볼 수 있다.
정리해보면, componentWillMount는 render함수가 실행되기 전에 해야 할 일을 구현하고,
componentDidMount는 render함수가 실행되고 나서 처리해야할 일이나 네트워크로 처리해야하는 코드들을 구현한다.
그리고 render함수가 실행되고 state나 props가 바뀌면 다시 render 함수가 실행되는 걸 볼 수 있다.
이때 shouldComponentUpdate에서 render 함수를 다시 호출할 필요가 있는지 없는 결정해
true를 반환하면 render를 호출하고, false를 반환하면 render를 호출하지 않는다.
-> 버튼을 클릭해보면 shouldComponentUpdate가 실행되는 걸 확인할 수 있음.
componentWillUnmount는 컴포넌트가 소멸될 때 호출되는데, 우리 코드에는 컴포넌트가 소멸되지 않아 호출되지 않았다.
함수에서 라이프사이클 구현하기 - 준비
함수형으론 라이프사이클을 어떻게 만들까?
일단 쉽게 알아보기 위해서 변수를 만들어보자.
var funcStyle = 'color:blue';
var funcId = 0;
function FuncComp(props) {
생략
console.log('%cfunc => render ' + (++funcId), funcStyle);
funcStyle은 알아보기 위한 CSS 속성값이고 funcId는 호출할 때마다 1씩 증가하는 변수이다.
함수에서 라이프사이클 구현하기 - useEffect
리액트 함수형 컴포넌트에선 훅을 사용한다. 라이프사이클을 구현하기 위해선 useEffect라는 훅을 사용하는데,
이 useEffect는 함수 컴포넌트(FuncComp)를 반환하기 전에 호출하면 된다.
useEffect는 첫 번째 인자와, 반환값은 무조건 함수여야 한다.
또한, 클래스형 컴포넌트의 componentWillMount나 componentDidUpdate와 비슷하다고 볼 수 있다.
그리고 여러 개의 useEffect를 사용할 수도 있다.
useEffect(function() {
console.log('%cfunc => useEffect number (componentDidMount & componentDidUpdate) ' + (++funcId), funcStyle);
document.title = number;
return function() {
console.log('%cfunc => useEffect number return (componentDidMount & componentDidUpdate) ' + (++funcId), funcStyle);
}
}, [number]);
useEffect(function() {
console.log('%cfunc => useEffect date (componentDidMount & componentDidUpdate) ' + (++funcId), funcStyle);
document.title = _date;
return function() {
console.log('%cfunc => useEffect date return (componentDidMount & componentDidUpdate) ' + (++funcId), funcStyle);
}
}, [_date]);
이런 식으로 구현해볼 수 있는데, 여기서 useEffect의 장점이 들어있다.
number이 바꼈을 때는 number의 useEffect만 호출되고, date가 바꼈을 때는 date의 useEffect만 호출된다.
즉, 바뀐 값에 대한 처리만 함으로써 성능을 굉장히 손쉽게 향상시킬 수 있다.
함수형 컴포넌트와 클래스형 컴포넌트가 사라지게!
function App() {
var [funcShow, setFuncShow] = useState(true);
var [classShow, setClassShow] = useState(true);
return (
<div className='App'>
<h1>Hello World</h1>
<input type="button" value="remove func" onClick={
function() {
setFuncShow(false);
}
} ></input>
<input type="button" value="remove class" onClick={
function(){
setClassShow(false);
}
}></input>
{funcShow ? <FuncComp initNumber={2}></FuncComp> : null }
{classShow ? <ClassComp initNumber={2}></ClassComp> : null}
</div>
);
}
이 코드를 작성하고 구현해보자.
remove 버튼을 눌렀을 때 componentWillUnmount가 호출되는 것을 볼 수 있다.
담소
처음엔 뭔 내용인지도 모르겠고 어려웠는데, 티스토리 쓰면서 정리가 된 듯!!
다음 목차는 React 라우터에 관한 내용인 것 같은데 벌써 기대가 된당 ㅎㅎ
'Library | Framework > React' 카테고리의 다른 글
[React] Ajax 찍먹하기 (0) | 2022.01.17 |
---|---|
[React] React Router 사용하기 (2) | 2022.01.17 |
[React] 클래스 스타일 vs 함수 스타일 (0) | 2022.01.14 |
[React] CRU 기능 보완, delete 기능 구현, Redux의 개념 (0) | 2022.01.11 |
[React] state값 수정, 저장하고 읽기 (0) | 2022.01.10 |
댓글