모던 리액트 Deep Dive 스터디

사용자 정의 훅과 고차 컴포넌트 중 무엇을 써야할까?

려낭 2024. 11. 16. 00:25

3.2.1 사용자 정의 훅

 

사용자 정의 훅

  • 서로 다른 컴포넌트 내부에서 같은 로직을 공유하고자 할 때 주로 사용되는 것.
  • 리액트에서만 사용할 수 있는 방식
  • 반드리 use로 시작하는 함수를 만들어야 한다.(해당 함수가 리액트 훅이라는 것을 인식할 수 있다)

사용자 정의 훅으로 분리하지 않는다면 fetch로 API를 호출해야 하는 모든 컴포넌트 내에서 각각 선언해서 구현해야 할 것이다.

useReducer을 사용하더라도 useEffect가 필요하기 때문에 훅을 중복해서 사용해야 할 것이다.

 

훅은 함수 컴포넌트 내부 혹은 사용자 정의 훅 내부에서만 사용할 수 있기 때문에 use로 시작하지 않거나 대문자로 시작하지 않는 함수 내부에서 훅을 호출한다면 에러가 발생한다.

 

 

3.2.2 고차 컴포넌트

 

컴포넌트 자체의 로직을 재사용하기 위한 방법이다.

리액트 훅, 사용자 정의 훅은 리액트에서만 사용할 수 있지만 고차 컴포넌트는 고차함수의 일종으로,

자바스크립트의 일급 객체, 함수의 특징을 이용하기 때문에 자바스크립트 환경에서도 널리 쓰일 수 있다.

 

리액트에서는 고차 컴포넌트 기법으로 다양한 최적화나 중복 로직 관리를 할 수 있다.

 

리액트에서 가장 유명한 고차 컴포넌트인 React.memo에 대해 알아보자.

 

 

React.memo

 

리액트 컴포넌트가 렌더링하는 조건에는 여러가지가 있는데 그 중 하나는 부모 컴포넌트가 새롭게 렌더링될 때 이다.

이는 자식 컴포넌트의 props 변경 여부와 관계없이 발생한다.

 

이처럼 props의 변화가 없음에도 컴포넌트의 렌더링을 방지하기 위해 만들어진 리액트의 고차 컴포넌트가 바로 React.memo이다.

 

React.memo는 렌더링하기에 앞서 props를 비교해 이전과 props가 같다면 렌더링 자체를 생략하고 이전에 기억해 둔 (memoization) 컴포넌트를 반환한다.

 

이로 인해 불필요한 렌더링 작업 생략이 가능하다.

 

 

고차 함수 만들어보기

 

먼저 자바스크립트에서 고차 함수를 만드는 것에 대해 살펴보자.

 

고차 함수 : 함수를 인수로 받거나 결과로 반환하는 함수

 

가장 대표적인 고차 함수로는 리액트에서 배열을 렌더링할 때 자주 사용하는 Array.prototype.memo이다.

 

직접 고차함수를 만들어보자.

function add(a) {
    return function (b) {
        return a + b;
    };
}

const result = add(1); // 여기서 result는 앞서 반환한 함수를 가리킨다.
const result2 = result(2); // 비로소 a와 b를 더한 3이 반환된다.

 

add(1)이라는 함수를 호출하는 시점에 1이라는 정보가 a에 포함되고, 이러한 정보가 담긴 함수를 result로 반환한다.

즉, result는 반환된 함수이며, 이후 result(2)를 호출함으로써 a와 b를 더한 3이 결과로 반환된다.

 

이러한 고차 함수를 활용하면 함수의 인수를 받거나 새로운 함수를 반환하여 다양한 작업을 수행할 수 있다.

리액트의 함수 컴포넌트도 함수이기 때문에 , 고차 함수를 활용하여 상태를 기억하거나 처리 로직을 전달할 수 있습니다.

 

 

 

고차 함수를 활용한 리액트 고차 컴포넌트 만들어보기

 

고차 컴포넌트를 사용하면 특정 페이지에서만 로그인이 필요할 경우 조건을 추가하여, 로그인 여부에 따라 컴포넌트의 렌더링을 결정할 수 있다.

 

function withLoginComponent<T>(Component: ComponentType<T>) {
    return function (props: T & LoginProps) {
        const { loginRequired, ...restProps } = props;
        if (loginRequired) {
            return <div>로그인이 필요합니다.</div>;
        }
        return <Component {...restProps as T} />;
    };
}

 

withLiginComponent라는 고차 컴포넌트를 작성하여 loginRequired라는 조건을 통해 로그인 여부에 따라 다른 UI를 보여준다.

 

주의사항

  • props 전달: 고차 컴포넌트를 사용할 때 원래 컴포넌트에 필요한 props가 제대로 전달되도록 주의해야 한다.
  • 여러 HOC 사용: 여러 개의 HOC를 중첩해서 사용할 수 있지만, 코드가 복잡해질 수 있으므로 유의해야 한다.

 

3.2.3 사용자 정의 훅과 고차 컴포넌트 중 무엇을 써야 할까?

 

사용자 정의 축과 고차 컴포넌트 모두 리액트 코드에서 어떠한 로직을 공통화해 별도로 관리할 수 있다는 특징이 있다.

애플리케이션 전반에 필요한 중복된 로직을 별도로 분리해 컴포넌트의 크기를 줄이고 가독성을 향상시키는 데 도움을 준다.

 

사용자 정의 훅이 필요한 경우

  • 공통 로직이 있는 경우: useEffect, useState 등 리액트 훅을 이용해 공통 로직을 쉽게 관리할 수 있다.
  • 비즈니스 로직의 재사용: 앱 내에서 특정 기능이나 상태가 여러 컴포넌트에서 재사용될 때 사용자 정의 훅이 적합하다.
  • 성능 측면에서 더 효율적: 고차 컴포넌트처럼 렌더링을 추가로 발생시키지 않고 로직만 제공하기 때문에 성능에 더 유리하다.

 

고차 컴포넌트를 사용해야 하는 경우

  • 컴포넌트의 렌더링을 조건부로 제어: 예를 들어, 특정 사용자만 접근 가능한 컴포넌트를 만들 때 유용하다.
  • 재사용 가능한 컴포넌트 확장: 고차 컴포넌트를 사용하면 컴포넌트의 UI와 관련된 로직을 추가하거나 변경할 수 있다.
  • 에러 처리: 공통적으로 에러 처리 로직을 추가하거나, 상태에 따라 다른 컴포넌트를 보여줘야 할 때도 사용된다.