React Hooks에 대하여

jin_sk·2020년 10월 14일
0

React

목록 보기
2/3

Hook 이란?

상태 관리가 가능하고 라이프사이클 API를 사용할 수 있는 함수형 컴포넌트

리액트에서 컴포넌트를 정의하는 방법

리액트에서 컴포넌트를 정의하는 방법은 두가지가 있다

클래스형 컴포넌트

  • state를 가지고 있어 상태 변화에 대한 관리를 할 수 있다
  • 단계별로 라이프 사이클을 경험할 수 있고, 라이프 사이클 API를 사용할 수 있다

함수형 컴포넌트

  • 클래스형 컴포넌트에 비해 선언하기가 간편하여 주로 화면을 그리는 역할을 한다
  • 메모리 자원을 클래스형 컴포넌트 보다는 덜 사용한다
  • state와 라이프사이클 API 사용이 불가능 하다

한마디로 클래스형은 stateful component , 함수형은 stateless component라고 할 수 있다

➡ 그러나 리액트 16.8 버전에 추가된 React Hook 으로 클래스형 컴포넌트에만 사용할 수 있었던 state, 라이프사이클 API를 함수형 컴포넌트에서도 사용할 수 있게 됐다


Hook이 생겨난 이유

1. 크고 복잡한 컴포넌트 때문에

  • 리액트에서는 고유한 역할을 가진 작은 단위의 컴포넌트로 분리하여 ➡ 커다란 코드를 만들고 ➡ 부작용을 최소화하는 방법을 가지고 있다
  • 또한 프레젠테이션 컴포넌트 (화면을 그리는 역할에 집중)컨테이너 컴포넌트 (상태, 로직을 가지고 있는 컨테이너)를 통해 컴포넌트의 재사용을 수월하게 할 수 있다
    하지만 컨테이너 컴포넌트는 상태와 비지니스 로직을 가지고 있기 때문에 이를 재사용하기가 쉽지 않다
  • 그래서 이 문제를 해결하기 위해 render props 그리고 고차 컴포넌트(HOC) 를 사용해야 했다
    • render props : 반복되는 로직을 쉽게 재사용 할 수 있게 해주고, 컴포넌트 코드를 작성하는 과정에서 컴포넌트를 함수로 감싸는 것이 아니라 JSX에서 렌더링 하는 방식으로 사용할 수 있게 해주는 패턴
    • HOC : 리액트 컴포넌트를 인자로 받아 새로운 리액트 컴포넌트를 반환하는 함수
  • 하지만 이런 패턴을 사용하면 컴포넌트를 재구성해야 하기 때문에 코드를 추적하기 어렵게 만들며, 재사용하기 위해 이런 패턴을 많이 사용하게 되어 Wrapper Hell 이 형성될 수 있다
  • 각 라이프사이클 API는 자주 그 사이클과 관련없는 로직이 섞여있다
    예를 들어 컴포넌트들은 componentDidMount 그리고 componentDidUpdate 로 데이터를 가져오는 것을 수행할 수 있다.
    그런데 같은 componentDidMount 메서드라도 이벤트 리스너를 설정하는 것과 같은 관계없는 일부 로직이 포함될 수도 있고, componentWillUnmont 에서 cleanup을 수행하기도 한다
    함께 변경괴는 상호 관련 부분 코드는 분리되지만, 이와 연관 없는 코드들은 단일 메서드로 결합된다
    이로인해 버그가 쉽게 발생하고, 무결성을 너무도 쉽게 해친다

Hook은 로직을 기반을 둔 작은 함수로 컴포넌트를 나눌 수 있다

2. 중복된 로직을 피하기 위해

  • 클래스형 컴포넌트에서 사용할 수 있는 라이프사이클 API는 종종 중복되는 로직을 각각 넣어주어야 한다
    componentDidMountcomponentDidUpdate로 데이터를 가져올 때 handleMainData 가 반복된다
  handleMainData = () => {
    fetch(
      `http://'API주소'/category?category=${this.state.currentCate}`
    )
      .then((res) => res.json())
      .then((res) => this.setState({ category: res }));
  };

  componentDidMount() {
    this.handleMainData();
  }

  componentDidUpdate(prevProps) {
    if (prevProps.match.params.slug !== this.props.match.params.slug) {
      this.handleMainData();
    }
  }

Hook은 상태 관련 로직을 추상화 할 수 있어 재사용이 가능하다

3. 클래스가 주는 혼동 때문에

  • 클래스가 주는 혼동의 원인은 바로 다른 언어들과는 다르게 동장하는 this 때문이다.
    컴포넌트 내부에서 사용하는 대부분의 함수들은 this를 바인딩 해주어야 하는데, 이는 실수를 유발하고 코드가 장황해질 수 있다는 문제점을 가진다
    ➡ 그런데 ES6의 arrow function 을 사용하면 this를 바인딩해주지 않아도 된다

Hook의 장점

  • 로직의 재사용 가능, 관리가 쉽다
    • Hook은 함수형 컴포넌트 이므로 함수 안에서 다른 함수를 호출하는 것으로 새로운 Hook을 만들어 볼 수 있기 때문이다
      따라서 리액트의 내장되어있는 Hook과 다른 사람들이 만든 여러 custom Hook을 레고처럼 조립해서 쉽게 custom Hook을 만들수 있다
  • 로직을 한 곳으로 모을수 있어서 가독성이 좋다
    • 클래스형 컴포넌트의 라이프사이클 API는 서로 다른 로직이 하나의 메서드에 섞여 있어서 가독성이 좋지 않다. Hook은 같은 로직을 한 곳으로 모을 수 있다
  • 정적 타입언어로 타입을 정의하기 쉽다
  • 상태 관리 방법을 더 쉽게 설명할 수 있다

참고
React 공식 문서
Hook의 등장배경
함수형 컴포넌트

0개의 댓글