React/문법

[React] - HOC (고차 컴포넌트)

위르겐 2023. 2. 23. 01:33

리액트의 고차함수에 대해서 알게 된 내용을

정리하고자 한다.

 

HOC(Higher-Order-Components)는 컴포넌트를 개발하는 하나의 패턴으로,

 컴포넌트를 인자로 받아 새로운 컴포넌트로 변환해 반환하는 함수이다.

 

다른 분들이 써놓으신 블로그랑

공식문서를 찾아보면서 

재밌어 보였고

고오급 기술이라는게 눈에 띄어서

공부해봤다.

 

HOC를 쉽게 정의하면 

상태관리 로직을 재사용하는 컴포넌트고 생각하면 된다.

 

 

 

여기서 사용하는 로직은

데이터를 받아와서 뿌려주는 정도로

아주 간단하게 작성했다.

 

바로 코드부터 살펴보자

import React, { ComponentType } from 'react';
import axios from 'axios';
import { useEffect, useState } from 'react';

export interface Props {
  albumId: number;
  id: number;
  thumbnailUrl: string;
  title: string;
  url: string;
}

export interface DataProps {
  data: Props[];
}

export const withHoc =
  (WrappedComponents: ComponentType<DataProps>) => () => {
    const [data, setData] = useState<Props[]>([]);
    const [loading, setLoading] = useState(true);

    useEffect(() => {
      const dataFetching = async () => {
        const res = await axios.get(
          'https://jsonplaceholder.typicode.com/photos'
        );
        setData(res.data.slice(0, 20));
        setLoading(false);
      };
      dataFetching();
    }, []);
    console.log(data);

    if (loading) return null;
    return <WrappedComponents data={data} />;
  };

export default withHoc;

 

우선 고차함수 컴포넌트 명은 with를 앞에 붙이는게 관례이고

https://jsonplaceholder.typicode.com/photos

위 주소는 알록달록한 단색 이미지를 받아오기 위한 

오픈API주소이다.

 

withHoc컴포넌트를 위에서부터 살펴보면

WrappedComponents를 인자로 받는데 이 인자의 타입은

컴포넌트 그 자체이기 때문에 ComponentType으로 타입을 지정해준다.

 

화살표함수가 두개 나오는데

첫 번째 화살표의 인자인

WrappedComponents 뒤의 화살표는

그 뒤의 비어있는 파라미터를 사용하는

함수 그 자체를 리턴하는 것이고

(함수를 리턴!)

빈 파라미터 뒤의 화살표는

그 뒤의 모든 로직들을 리턴하는 것이다.

 

화살표 함수 두개를 중첩했다고 보면 된다.

 

 

로직에 대한내용은 간단하다

1. 데이터를 받아오고 data라는 state에 넣어준다.

2. data를 받아오기 전까지는 loading이 true이므로 null을 리턴한다.

 

 

마지막줄

 

    return <WrappedComponents data={data} />;

 

WrappedComponents에

(맨앞글자를 대문자로한 후 아무 이름이나 지어주면 된다.)

data라는 state를 props로 넘겨준다.

 

 

 

자 그럼

 

이제 이 withHoc 컴포넌트를 사용하는

컴포넌트를 봐보자.

 

import styles from './style.module.scss';
import { DataProps, Props } from '@/app/components/withHoc';
import { withHoc } from '@/app/components/withHoc';

const HomeScreen = (props: DataProps) => {
  const data = props.data;

  return (
    <div className={styles.container}>
      {data.map((detailData: Props) => {
        return (
          <div key={detailData.url} className={styles.itemBox}>
            <img src={detailData.url} className={styles.item}></img>
          </div>
        );
      })}
    </div>
  );
};

export default withHoc(HomeScreen);

 

해당 데이터의 이미지 url을 받아 

map으로 뿌려준다

 

withHoc 컴포넌트에서

데이터를 임의로 20개만 지정해주었다.

 

여기서 핵심은

가장 마지막 줄에

export default withHoc(HomeScreen);

이 부분인데

 

export된 withHoc으로 

현재 컴포넌트를 감싸면 

withHoc컴포넌트의 로직을 재사용할 수 있다.

 

 

 

 

 

 

 

이렇게

HOC(고차 컴포넌트)에 대해 알아봤는데

상태관리 로직을 재사용하는

또 다른 방법은 커스텀 훅이 있다

 

사실 나는 커스텀 훅을 먼저 알게 됐고

유용하게 사용했기 때문에

HOC를 공부하면서

오히려 코드가 복잡하고 컴포넌트가 중첩되어

커스텀 훅보다 좋은 점을 찾기 힘들었다.

 

클래스형 컴포넌트가 먼저나오고

이 때는 HOC만을 이용해 로직을 재사용했으며

리액트 16.8 이후부터는

hooks가 등장하여 로직을 재사용하는

커스텀 훅이라는 게 생겼기 때문에

HOC를 커스텀 훅으로 대체할 수 있게 된 것이 아닐까 라는 생각을 해본다.

 

그래도 HOC를 배우며 알게 됐던것은

컴포넌트의 타입지정이랑

화살표 함수의 중첩

그리고 이 코드들을 작성하기 위해

간단한 웹팩설정도 동반했다는 것이다.

 

 

최근 입사 면접을 보러다니고 있는데

그 과정에서 내가 정말 부족하고

 더 공부를 많이 해야겠다는 생각을 한다.

 

준비된 자에게 기회가 찾아온다.

열심히 하자.

 

반응형

'React > 문법' 카테고리의 다른 글

[React] 리렌더링 발생 조건  (0) 2022.07.31
[React] useEffect (3)  (0) 2022.05.31
[React] useEffect (2)  (0) 2022.05.31
[React] useEffect (1)  (0) 2022.05.31
[React] input을 이용한 리스트 추가  (0) 2022.05.26