Effect Hook (feat. lifecycle in React)

들어가기 전에...

함수 컴포넌트의 useEffect Hook은 class 컴포넌트의 생명주기로 미루어 봤을 때, componentDidMount, componentDidUpdate, componentWillUnmount가 합쳐진 것으로 봐도 좋다.

useEffect Hook을 이용해서 컴포넌트가 렌더링 이후에 어떤 일을 수행해야 하는지 알려준다. 리액트는 우리가 넘긴 함수를 기억해둔다. 여기서 이 함수를 ‘effect’라고 부른다.

useEffect를 컴포넌트 내부에 두는 이유는, effect를 통해 state 변수(또는 그 어떤 prop에도)에 접근할 수 있게 됩니다.

아래의 코드에서 클래스 컴포넌트와 함수 컴포넌트의 구조를 비교하는 동시에, 클래스 생명주기와 Effect Hook이 어떻게 다른지 비교할 수 있습니다. 처음 화면이 랜더링 될 때부터, 화면에서 나가기 할 때까지 어떤 순서로 작동이 하는지 알아보기 위해서 각 순간순간마다 콘솔에 값이 출력되게끔 console.log()를 작성해두었습니다.

클래스 컴포넌트 (Lifecycle)

import Router from "next/router";
import { Component, createRef } from "react";

interface IPrev {
  count: number;
}

export default class LifecycleClassPage extends Component {
  state = {
    count: 0,
  };

  inputRef = createRef<HTMLInputElement>();

  componentDidMount() {
    this.inputRef.current?.focus();
    console.log("안녕!");
  }

  componentDidUpdate() {
    console.log("반가워!");
  }

  componentWillUnmount() {
    alert("잘가!");
  }

  onClickCount = () => {
    this.setState((prev: IPrev) => ({
      count: prev.count + 1,
    }));
  };

  onClickMove = () => {
    Router.push("/");
  };

  render() {
    return (
      <>
        <input type="password" ref={this.inputRef} />
        <div>카운트 {this.state.count}</div>
        <button onClick={this.onClickCount}>더하기 1</button>
        <div>이것은 클래스 컴포넌트입니다.</div>
        <button onClick={this.onClickMove}>나가기</button>
      </>
    );
  }
}
  1. 화면이 랜더링 되었을 때 임의의 태그에 자동으로 포커싱을 하고 싶은 경우, componentDidMount() 부분에서 기능을 추가하면 된다.

  1. 처음 화면이 마운트 된 직후, 콘솔에 안녕!이 출력되는 것을 확인할 수 있다.

  1. '더하기 1' 버튼을 누르고 count 스테이트를 변경시킴으로써, 컴포넌트가 업데이트 되었을 때, 반가워!가 출력되는 것을 확인할 수 있다.

  1. '나가기' 버튼을 누르고 다른 페이지로 라우팅함으로써, 잘가!가 출력되는 것을 확인할 수 있다.

함수 컴포넌트 (Effect Hook)

import { useRouter } from "next/router";
import { useEffect, useRef, useState } from "react";

export default function LifecycleFunctionPage() {
  const router = useRouter();
  const [count, setCount] = useState(0);
  const inputRef = useRef<HTMLInputElement>(null);

  useEffect(() => {
    console.log("안녕!");
    inputRef.current?.focus();
    return () => {
      alert("잘가!");
    };
  }, []);

  useEffect(() => {
    console.log("반가워!");
  }, []);

  const onClickCount = () => {
    setCount((prev) => prev + 1);
  };

  const onClickMove = () => {
    router.push("/");
  };

  return (
    <>
      <input type="password" ref={inputRef} />
      <div>카운트: {count}</div>
      <button onClick={onClickCount}>더하기 1</button>
      <div>이것은 함수 컴포넌트 입니다.</div>
      <button onClick={onClickMove}>나가기</button>
    </>
  );
}
  1. 화면이 랜더링 되었을 때 임의의 태그에 자동으로 포커싱을 하고 싶은 경우, useEffect() 부분에서 기능을 추가하면 된다.

  1. 처음 화면이 마운트 된 직후, 콘솔에 안녕!이 출력되는 것을 확인할 수 있다.

  1. '더하기 1' 버튼을 누르고 count 스테이트를 변경시킴으로써, 컴포넌트가 업데이트 되었을 때, 반가워!가 출력되는 것을 확인할 수 있다.

  1. '나가기' 버튼을 누르고 다른 페이지로 라우팅함으로써, 잘가!가 출력되는 것을 확인할 수 있다.

좋은 웹페이지 즐겨찾기