[React] 클래스형 컴포넌트 vs 함수형 컴포넌트

Main·2023년 8월 4일
0

React

목록 보기
6/31
post-thumbnail

클래스형 컴포넌트?

react 컴포넌트 선언 방식 중 하나로 class를 이용하여 컴포넌트를 구성하는 방식입니다.
현재는 함수형 컴포넌트 사용이 권장되지만 함수형 컴포넌트가 나오기 예전 프로젝트의 유지보수를 위해 클래스형 컴포넌트에 대한 개념의 이해가 필요합니다.

클래스형 컴포넌트 사용

  • 클래스형 컴포넌트는 class 키워드가 필요하며 react의 Compenent를 상속받아야합니다.
  • render() 메소드를 통해 UI를 반환합니다.
  • 상태관리 및 lifeCycle을 setState와 lifeCycle 메소드를 통해 관리합니다.
import React, { Component } from "react";

export default class ClassTest extends Component {
  // state 초기값 설정
  state = {
    nickname: "",
    age: 0,
    disabled: true,
  };

  // nickname, age 상태가 바뀔 때 마다 실행
  componentDidUpdate(prevProps, prevState) {
    // 조건문을 주어서 무한 반복을 막아야함
    // state 값이 변경됬을 경우에만 실행되도록 함
    if (
      this.state.nickname !== prevState.nickname ||
      this.state.age !== prevState.age
    ) {
      if (this.state.nickname && this.state.age !== "0") {
        this.setState({ disabled: false });
      } else {
        this.setState({ disabled: true });
      }
    }
  }

  changeNickname = (e) => {
    this.setState({ nickname: e.target.value });
  };

  changeAge = (e) => {
    this.setState({ age: e.target.value });
  };

  onSubmit = (e) => {
    e.preventDefault();
    console.log(`닉네임: ${this.state.nickname} 나이: ${this.state.age}`);
  };

  render() {
    return (
      <form onSubmit={this.onSubmit}>
        <div>
          <label htmlFor="input-nickname">닉네임 : </label>
          <input
            id="input-nickname"
            value={this.state.nickname}
            onChange={this.changeNickname}
            type="text"
          />
        </div>
        <div>
          <label htmlFor="input-age"> 나이 : </label>
          <input
            style={{ width: "30px", margin: "20px 0px" }}
            id="input-age"
            value={this.state.age}
            onChange={this.changeAge}
            type="number"
            min="0"
          />
        </div>
        <button type="submit" disabled={this.state.disabled}>
          확인
        </button>
      </form>
    );
  }
}

클래스형 컴포넌트의 lifeCyle

[출처]: https://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/

(1) 마운트 : 컴포넌트가 렌더링이 되고 최초 한번 실행

constructor => render => ref => compoentDidMout

  • constructor : 컴포넌트가 새로 생성이 되고 렌더링(DOM 생성) 이전에 수행이 되는 클래스 생성자 메서드를 의미합니다.
    생성자로 props를 전달받아 state를 초기화해야 할 때 사용하는 메서드
    state를 초기화하지 않는다면 구현하지 않아도 됩니다.
    반드시 첫 줄에 super(props) 를 호출해야하며 그렇지 않은 경우 오류가 발생합니다.
  • render : 화면에 출력할 내용을 생성하여 반환합니다.
    prposstate 값으로만 생성해야합니다.
    Side-Effect를 발생시켜서는 안됩니다.
  • ref : 컴포넌트 라이프 사이클 내에서 유지가 되며, 변경이 가능한 변수이며, 값이 변할 때 렌더링이 되지 않습니다.
  • compoentDidMout : render()의 반환 값이 DOM에 반영된 후 호출됩니다.
    컴포넌트가 DOM에 반영된 시점이므로 DOM으로부터 필요정보 조회가 가능합니다.
    setState() 메서드 호출과 Side-Effect 코드 실행이 가능합니다.

(2) 업데이트 : props, state가 변경될 때 마다 실행

setState/props 변경 시 => render => componentDidUpdate

  • componentDidUpdate : 컴포넌트의 props, state 변경시 마다 실행됩니다.

(3) 언마운트 : DOM에서 컴포넌트가 제거될 때

compoentWillUnmount => 소멸

  • compornetWillUnmount : 컴포넌트가 제거되기 직전 실행됩니다.

함수형 컴포넌트 ?

react 컴포넌트 선언 방식 중 하나로 함수를 이용하여 컴포넌트를 구성하는 방식입니다.
React 16.8 버전 이후에 도입된 훅(Hook) API와 함께 사용되면서 매우 간결하고 쉽게 코드를 작성할 수 있습니다.
현재는 함수형 컴포넌트 작성이 권장됩니다.

함수형 컴포넌트 사용

  • 함수형 컴포넌트는 함수를 사용하여 정의합니다.
  • return를 통해 UI를 반환합니다.
  • 상태관리 및 lifeCycle을 useState hook, useEffect hook을 통해 관리합니다.

    useState : 함수형 컴포넌트에서 상태관리를 위해 사용되는 hook으로 state 속성 값, setState()메소드를 반환하는 함수입니다. 인자 값으로 초기 state값을 받습니다.

    useEffect : 함수형 컴포넌트에서 lifeCycle 관리를 위해 사용되는 hook 으로 의존성배열(dependency Array)를 통해 라이프 사이클의 실행 시점을 설정할 수 있습니다.

import React, { useEffect, useState } from "react";

export default function FucionCompoent() {
  // 초기값 설정
  const [nickname, setNickname] = useState("");
  const [age, setAge] = useState(0);
  const [disabled, setDisabled] = useState(true);

  function changeNickname(e) {
    setNickname(e.target.value);
  }

  function changeAge(e) {
    setAge(e.target.value);
  }

  function onSubmit(e) {
    e.preventDefault();
    console.log(`닉네임: ${nickname} 나이: ${age}`);
  }
  // nickname, age 상태가 변경될 때 마다 실행
  useEffect(() => {
    if (nickname && age) {
      setDisabled(false);
    } else {
      setDisabled(true);
    }
  }, [nickname, age]);

  return (
    <form onSubmit={onSubmit}>
      <div>
        <label htmlFor="input-nickname">닉네임 : </label>
        <input
          id="input-nickname"
          value={nickname}
          onChange={changeNickname}
          type="text"
        />
      </div>
      <div>
        <label htmlFor="input-age"> 나이 : </label>
        <input style={{width:"30px", margin:"20px 0px"}} id="input-age" value={age} onChange={changeAge} type="number" />
      </div>
      <button type="submit" disabled={disabled}>
        확인
      </button>
    </form>
  );
}

함수형 컴포넌트의 lifeCycle

[출처] https://wavez.github.io/react-hooks-lifecycle/

(1) 마운트

컴포넌트 호출 => useMemo() => return => useEffect(), useLayoutEffect()

  • 컴포넌트가 호출이 되었을 때 가장 먼저 호출이 되는 것은 컴포넌트 내부입니다.
  • useMemo() : 함수의 반환 값을 메모이제이션 하여 캐시에 저장하는 hook입니다.
  • return : 함수 컴포넌트의 UI를 반환합니다.
  • useEffect() : useEffect hook을 통하여서 Mounting/Updating/Unmounting 처리가 가능합니다. 의존성 배열(dependency)에 의해 lifeCycle 처리를 관리할 수 있습니다.
    useEffect의 경우 렌더링 이후 실행되며, 비동기적으로 처리됩니다.
  • useLayoutEffect : useEffect와 기능은 동일하지만 렌더링이 발생하기 전에 실행되어 paint 단계 이전 실행되며, 동기적으로 처리됩니다. 주로 렌더링 시 깜빡임 현상을 해결하기 위해 사용됩니다.

(2) 업데이트

props/state 변경 => useEffect(), useLayoutEffect()

(3) 언마운트

cleanup function => 제거

  • cleanup function : useEffect에서 return으로 구현하며, 훅이 정리(clean up)되는 시점에서 실행되는 함수로 주로 비동기 처리 취소, 이벤트 제거에 사용됩니다. CompoentWillUnmonut와 같은 역할을 합니다.

정리

클래스형 컴포넌트와 함수형 컴포넌트는 컴포넌트 선언 방식, UI 반환 방식, state 및 lifeCycle 관리 방식 등의 차이점이 존재하며, 현재는 함수형 컴포넌트 사용이 권장되지만, 함수형 컴포넌트가 나오기 이전의 프로젝트를 유지 보수하기 위해서는 클래스형 컴포넌트의 개념을 숙지해야한다.


출처

클래스형과 함수형 차이
[React] 함수형 컴포넌트 생명주기(lifeCycle)이해하기

profile
함께 개선하는 개발자

0개의 댓글