쉽게 생명주기를 생각했을떄
1.render(그리기)
2.componentDidMount(그리고 난뒤)
3.componentDidUpdate(그리고 난 뒤 변경됬때)
4.componentWillUnmount(그리고 난뒤 사라질때)
이렇게 총 크게 4가지로 구분이 된다.
가장먼저 화면에 렌더가 진행되고,componentDidMount 에서 최초 1회 실행을 해주며,componentDidUpdate 에서 상태값이 변경되고 화면에 리렌더링이 될때마다 실행된다.
마지막에 componentWillUnmount는 컴포넌트가 종료될때 실행한다.
즉 리액트는 컴포넌트의 생명주기가 그리고 생성한 후 업데이트를 마친후 사라진다.
import { Component, createRef } from "react";
import Router from "next/router";
interface IPrev {
count: number;
}
export default class index extends Component {
inputRef = createRef<HTMLInputElement>();
state = {
count: 0,
};
// 화면이 render 되고 나서 딱 한번 실행되는 함수
componentDidMount() {
console.log("마운트됌");
this.inputRef.current?.focus();
}
// 상태값이 바뀌면서 리렌더링이 될때 계속 그려짐
componentDidUpdate() {
console.log("수정되고 다시 그려짐");
}
//컴포넌트 종료
componentWillUnmount() {
console.log("컴포넌트 사라짐!");
}
onClickMove = () => {
Router.push("/");
};
onClickCounter = () => {
this.setState((prev: IPrev) => ({
count: prev.count + 1,
}));
};
render() {
return (
<div>
<input type="text" ref={this.inputRef}></input>
<div>현재 카운트는:{this.state.count}</div>
<button onClick={this.onClickCounter}> 카운트 올리기!</button>
<button onClick={this.onClickMove}>
나가기!!!!
</button>
</div>
);
}
}
그렇다면 함수형에서는 생명주기가 존재하지 않을까?? 존재한다. useEffect로 클래스 컴포넌트의 생명주기를 구현할 수 있다. useEffect에서 제일 마지막의 의존성 배열에 값을 넣어주고 안넣어주느냐에 따라서 다르게 동작이 될 수 있다.
즉 useEffect에 의존성 배열이 없다면 componentDidMount() 와 동일한 역할을 하고,
의존성 배열이 있다면 componentDidUpdate()와 동일한 역할을 한다. useEffect 안에 return 을 해주게 되면 componentWillUnmount() 와 동일한 역할을 한다.
따라서 함수형으로 코드를 변경하면...
import { useRef, useState, useEffect } from "react";
import { useRouter } from "next/router";
export default function index() {
const [count, setCount] = useState(0);
const inputRef = useRef<HTMLInputElement>(null);
const Router = useRouter();
useEffect(() => {
console.log("수정되고 다시 그려짐");
}, [count]);
// DidMount와 WillUnmount를 합치기
useEffect(() => {
console.log("마운트됌");
inputRef.current?.focus();
return () => {
console.log("컴포넌트 사라짐");
};
}, []);
const onClickMove = () => {
Router.push("/");
};
const onClickCounter = () => {
setCount((count) => count + 1);
};
return (
<div>
<input type="text" ref={inputRef}></input>
<div>현재 카운트는:{count}</div>
<button onClick={onClickCounter}> 카운트 올리기!</button>
<button onClick={onClickMove}>
나가기!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
</button>
</div>
);
}