본문 바로가기
FrontEnd/React

리액트 | 리액트에서의 고차 컴포넌트 활용하기

by Noo-Dabee 2023. 4. 8.
반응형

리액트는 현재 프론트엔드 개발에서 가장 인기 있는 라이브러리 중 하나입니다. 이러한 인기는 리액트가 개발자들에게 제공하는 다양한 기능과 유연성 때문입니다. 그 중에서도 고차 컴포넌트(Higher-Order Component)는 리액트에서 매우 유용한 기능 중 하나입니다. 이번 글에서는 고차 컴포넌트가 무엇인지, 어떻게 활용할 수 있는지, 그리고 테스트 주도 개발(Test-Driven Development)과 타입스크립트(Typescript)와 함께 고차 컴포넌트를 사용하는 방법에 대해 알아보겠습니다.

고차 컴포넌트란?

고차 컴포넌트는 리액트에서 컴포넌트를 감싸는 함수입니다. 이 함수는 컴포넌트를 인자로 받아서 새로운 컴포넌트를 반환합니다. 이렇게 반환된 컴포넌트는 원래의 컴포넌트를 감싸고 있으며, 그 안에서 추가적인 기능을 제공합니다. 이러한 고차 컴포넌트는 컴포넌트의 재사용성을 높이고, 코드의 중복을 줄이며, 코드의 가독성을 높이는 데에 매우 유용합니다.

고차 컴포넌트 활용하기

고차 컴포넌트를 활용하는 방법은 다양합니다. 이번에는 몇 가지 예시를 살펴보겠습니다.

1. 인증 기능 추가하기

인증 기능은 대부분의 웹 애플리케이션에서 필수적인 기능 중 하나입니다. 이를 구현하기 위해서는 매번 인증 기능을 추가하는 것은 매우 번거로운 일입니다. 이때 고차 컴포넌트를 사용하면 매우 간단하게 인증 기능을 추가할 수 있습니다.

const withAuth = (Component) => {
  const AuthenticatedComponent = (props) => {
    const isAuthenticated = checkAuth(); // 인증 여부 확인
    if (isAuthenticated) {
      return <Component {...props} />;
    } else {
      return <Redirect to="/login" />;
    }
  };
  return AuthenticatedComponent;
};

const MyComponent = () => {
  return <div>인증된 컴포넌트</div>;
};

const AuthenticatedComponent = withAuth(MyComponent);

위 코드에서 withAuth 함수는 MyComponent를 인자로 받아서 AuthenticatedComponent를 반환합니다. AuthenticatedComponentMyComponent를 감싸고 있으며, 인증 여부를 확인한 후에 MyComponent를 렌더링하거나 로그인 페이지로 리다이렉트합니다.

2. 데이터 로딩 상태 관리하기

데이터 로딩 상태는 대부분의 웹 애플리케이션에서 중요한 부분입니다. 이를 구현하기 위해서는 매번 데이터 로딩 상태를 관리하는 것은 매우 번거로운 일입니다. 이때 고차 컴포넌트를 사용하면 매우 간단하게 데이터 로딩 상태를 관리할 수 있습니다.

const withLoading = (Component) => {
  const LoadingComponent = ({ isLoading, ...props }) => {
    if (isLoading) {
      return <div>Loading...</div>;
    } else {
      return <Component {...props} />;
    }
  };
  return LoadingComponent;
};

const MyComponent = ({ data }) => {
  return <div>{data}</div>;
};

const LoadingComponent = withLoading(MyComponent);

위 코드에서 withLoading 함수는 MyComponent를 인자로 받아서 LoadingComponent를 반환합니다. LoadingComponentMyComponent를 감싸고 있으며, isLoading prop을 통해 데이터 로딩 상태를 관리합니다. 데이터 로딩 중일 때는 "Loading..."을 렌더링하고, 데이터 로딩이 완료되면 MyComponent를 렌더링합니다.

TDD와 함께 고차 컴포넌트 사용하기

테스트 주도 개발(Test-Driven Development, TDD)은 개발자들 사이에서 매우 인기 있는 개발 방법 중 하나입니다. 이 방법은 테스트 코드를 먼저 작성하고, 그에 맞게 코드를 작성하는 방법입니다. 이를 통해 코드의 품질을 높이고, 버그를 줄일 수 있습니다. 이번에는 TDD와 함께 고차 컴포넌트를 사용하는 방법에 대해 알아보겠습니다.

1. 테스트 코드 작성하기

먼저 테스트 코드를 작성해야 합니다. 이때는 고차 컴포넌트를 사용하기 전에 일반적인 컴포넌트를 테스트하는 것과 동일한 방법으로 테스트 코드를 작성합니다.

describe("MyComponent", () => {
  it("renders correctly", () => {
    const tree = renderer.create(<MyComponent data="Hello, world!" />).toJSON();
    expect(tree).toMatchSnapshot();
  });
});

위 코드에서는 MyComponent를 렌더링하고, 그 결과를 스냅샷으로 저장합니다. 이렇게 저장된 스냅샷은 이후에 컴포넌트의 변경 여부를 확인하는 데에 사용됩니다.

2. 고차 컴포넌트 작성하기

다음으로는 고차 컴포넌트를 작성해야 합니다. 이때는 테스트 코드에서 작성한 스냅샷을 기반으로 고차 컴포넌트를 작성합니다.

const withData = (Component) => {
  const DataComponent = ({ data, ...props }) => {
    return <Component data={data} {...props} />;
  };
  return DataComponent;
};

const MyComponentWithData = withData(MyComponent);

위 코드에서 withData 함수는 MyComponent를 인자로 받아서 DataComponent를 반환합니다. DataComponentMyComponent를 감싸고 있으며, data prop을 추가로 전달합니다.

3. 테스트 코드 수정하기

마지막으로 테스트 코드를 수정해야 합니다. 이때는 고차 컴포넌트를 사용한 컴포넌트를 테스트하는 것과 동일한 방법으로 테스트 코드를 수정합니다.

describe("MyComponentWithData", () => {
  it("renders correctly", () => {
    const tree = renderer
      .create(<MyComponentWithData data="Hello, world!" />)
      .toJSON();
    expect(tree).toMatchSnapshot();
  });
});

위 코드에서는 MyComponentWithData를 렌더링하고, 그 결과를 스냅샷으로 저장합니다. 이렇게 저장된 스냅샷은 이후에 컴포넌트의 변경 여부를 확인하는 데에 사용됩니다.

타입스크립트와 함께 고차 컴포넌트 사용하기

타입스크립트(Typescript)는 최근 프론트엔드 개발에서 매우 인기 있는 언어 중 하나입니다. 이 언어는 정적 타입 검사를 제공하여 코드의 안정성을 높이는 데에 매우 유용합니다. 이번에는 타입스크립트와 함께 고차 컴포넌트를 사용하는 방법에 대해 알아보겠습니다.

1. 타입 정의하기

먼저 타입을 정의해야 합니다. 이때는 React.FC 타입을 사용하여 컴포넌트의 타입을 정의합니다.

type MyComponentProps = {
  data: string;
};

const MyComponent: React.FC<MyComponentProps> = ({ data }) => {
  return <div>{data}</div>;
};

위 코드에서는 MyComponent의 props 타입을 MyComponentProps로 정의하고, React.FC<MyComponentProps> 타입을 사용하여 MyComponent의 타입을 정의합니다.

2. 고차 컴포넌트 작성하기

다음으로는 고차 컴포넌트를 작성해야 합니다. 이때는 React.ComponentType 타입을 사용하여 컴포넌트의 타입을 정의합니다.

const withData = <P extends MyComponentProps>(
  Component: React.ComponentType<P>
) => {
  const DataComponent: React.FC<P> = ({ data, ...props }) => {
    return <Component data={data} {...props} />;
  };
  return DataComponent;
};

const MyComponentWithData = withData(MyComponent);

위 코드에서 withData 함수는 MyComponent를 인자로 받아서 DataComponent를 반환합니다. DataComponentMyComponent를 감싸고 있으며, data prop을 추가로 전달합니다. 이때 P extends MyComponentPropsMyComponent의 props 타입을 상속받는 제네릭 타입입니다.

3. 컴포넌트 사용하기

마지막으로 컴포넌트를 사용할 때는 타입을 명시적으로 지정해야 합니다.

const App = () => {
  return <MyComponentWithData data="Hello, world!" />;
};

위 코드에서는 MyComponentWithData를 사용할 때 타입을 명시적으로 지정합니다.

 

결론

이번 글에서는 리액트에서 고차 컴포넌트를 활용하는 방법에 대해 알아보았습니다. 고차 컴포넌트는 컴포넌트의 재사용성을 높이고, 코드의 중복을 줄이며, 코드의 가독성을 높이는 데에 매우 유용합니다. 또한 테스트 주도 개발(Test-Driven Development)과 타입스크립트(Typescript)와 함께 고차 컴포넌트를 사용하는 방법에 대해서도 알아보았습니다. 이러한 기술들을 활용하여 더욱 효율적이고 안정적인 리액트 애플리케이션을 개발할 수 있습니다.

 

 

반응형

댓글