본문 바로가기
리액트

[react] 리액트 훅(react hook)이란? - 클래스형 컴포넌트와 비교

by jaewooojung 2019. 7. 30.

ReactJS


React Hook

React 16.8 버전부터 정식으로 릴리즈 된 React Hook에 대해 살펴보겠습니다.

 

1. 리액트 컴포넌트의 두 가지 형태

리액트에서는 두 종류의 컴포넌트가 사용됩니다. 클래스형 컴포넌트함수형 컴포넌트입니다.

기존의 개발방식에서는 주로 함수형 컴포넌트를 사용하며, 상태 관리나(state) 생명주기 관련(life cycle method) 기능이 필요할 때만 클래스형 컴포넌트를 활용하였습니다. 주로 함수형 컴포넌트를 사용했던 이유는 클래스형 컴포넌트의 단점 때문입니다.

 

 

2. 클래스형 컴포넌트의 단점

2-1. 복잡성과 길이

클래스형 컴포넌트는 constructor, this, binding과 같은 여러 규칙을 따라야 하며, 이로 인해 코드가 복잡하고 길어질 수 있습니다. 클래스 기반의 구조는 체계적인 코드관리에 용이하지만, UI개발 특성상 때때로 불필요하게 복잡하게 느껴질 수 있습니다.

2-2. 로직 재사용의 어려움

클래스형 컴포넌트에서는 High-Order Components(HOC, 다른 컴포넌트를 받아 새로운 컴포넌트를 반환하는 함수)를 통해 재사용성을 얻을 수 있으나, 특정 DOM 처리나 API 호출, 상태 관리 같은 로직의 재사용은 제한적입니다. 동일한 로직을 여러 life cycle method에 중복해서 넣어야 하는 상황이 자주 발생합니다.

 

 

3. hook의 등장

클래스형 컴포넌트의 단점들에도 불과하고, 그동안 클래스형 컴포넌트를 사용했던 이유는 위에서 언급했듯이 상태관리와 life cycle method의 사용 때문이었습니다. 복잡하고 뚱뚱하지만 클래스의 힘을 빌려야만 React가 원활하게 작동할 수 있었던 것이죠.

 

그런데 hooks의 등장으로 인해 함수형 컴포넌트에서도 이러한 클래스형 컴포넌트의 작업들을 할 수 있게 되었습니다. 특히나 OOP를 선호하지 않는 개발자에게 있어서 React를 함수로 사용할 수 있게 되었다는 것은 매우 환영할만한 일이죠.

 

3-1. 가독성 향상

굳이 복잡한 클래스형 컴포넌트를 사용할 필요가 없어지면서 react 프로젝트의 가독성이 크게 증가합니다. 자바스크립트 개발자들은 깔끔한 함수형 개발에 익숙하죠.

3-2. 로직 재사용

hook을 사용하는 함수형 컴포넌트에서는 필요한 로직을 커스텀 훅으로 만들고 이를 필요한 곳에 삽입하기만 하면 됩니다. 이는 로직의 재사용성을 크게 향상하며, 개발 과정을 간소화합니다. hook의 등장은 개발자에게 더 직관적이고 효율적인 컴포넌트 구조를 제공하며, React 개발의 패러다임을 전환시키는 중요한 계기가 되었습니다.

 

 

4. 성능 비교 - 클래스형 vs 함수형

함수형 컴포넌트의 성능에 관한 포스트입니다.
https://medium.com/missive-app/45-faster-react-functional-components-now-3509a668e69f

 

45% Faster React Functional Components, Now

Jump to TL;DR at the end to see one easy change you can apply to your React code to get a free speedup. For more details, read on.

medium.com

페이스북에서 2015년 10월에 "향후에 함수형 컴포넌트의 performance를 상승시킬 것"이라고 발표한 바는 있습니다만 이후에 실제 상승결과를 언급한 적은 없습니다. 다만 위 포스트처럼 함수형 컴포넌트의 performance 우위를 측정한 글들을 종종 볼 수 있죠. 요약하면 대략 6% ~ 45% 상승했다고 말합니다.

 

 

5. 코드 비교

두 가지 컴포넌트의 차이를 간단한 예시를 통해 살펴보겠습니다.
동일한 기능(카운터)을 클래스형 컴포넌트와 함수형 컴포넌트로 각각 구현해 보겠습니다.

5-1. 클래스형 컴포넌트

import React from "react";

class App extends React.Component {
  state = {
      number: 0
  };
  render() {
    return (
      <div style={{ "textAlign": "center" }}>
        <div style={{ "fontSize": "100px" }}>{this.state.number}</div>
        <button onClick={this.handleClickIncrement}>더하기</button>
        <button onClick={this.handleClickDecrement}>빼기</button>
      </div>
    );
  }
  handleClickIncrement = () => {
    this.setState(state => ({
      number: state.number + 1
    }));
  };
  handleClickDecrement = () => {
    this.setState(state => ({
      number: state.number - 1
    }));
  };
}

export default App;

 

숫자를 다루기 위해 컴포넌트에 state을 선언하고 this를 통해 state에 접근합니다.

 

5-2. 함수형 컴포넌트

import React, { useState } from "react";

const App = () => {
  const [number, setNumber] = useState(0);
  const handleClickIncrement = () => {
    setNumber((prev) => prev + 1);
  };
  const handleClickDecrement = () => {
    setNumber((prev) => prev - 1);
  };
  return (
    <div style={{ textAlign: "center" }}>
      <div style={{ fontSize: "100px" }}>{number}</div>
      <button onClick={handleClickIncrement}>더하기</button>
      <button onClick={handleClickDecrement}>빼기</button>
    </div>
  );
};

export default App;

 

useState hook을 사용하여 state을 관리합니다. this가 사라지고 context(this가 가리키는 것)의 혼란이 사라졌습니다.

 

state의 선언과 변경이 훨씬 직관적으로 바뀐 것이 보이시나요?

useState은 함수형 컴포넌트에서 state의 선언과 관리를 도와주는 hook입니다. 이 hook을 호출하는 것 만으로 해당 컴포넌트의 state에 관련된 모든 기본 로직을 가져올 수 있습니다. 위 코드에서는 number라는 state과 setNumber라는 state 변경함수를 useState을 통해 선언하였습니다.

 

useState에 관한 자세한 설명은 아래 글을 참고해 주세요.

2019.08.02 - [react] 예제로 따라 하는 리액트 훅(hook) - useState

 

[react] 예제로 따라하는 리액트 훅(hook) - useState

간단한 예제를 통해서 리액트 훅의 useState을 살펴보겠습니다. 작업의 처음단계부터 하나씩 진행하니 리액트에 처음 입문하시는 분들도 천천히 진행해보시길 바랍니다. create-react-app으로 프로젝

codingbroker.tistory.com



        
답변을 생성하고 있어요.