Higher Order Component(HOC) 활용 제대로 하기

Dan·2023년 2월 27일
0

리액트

목록 보기
17/17
post-thumbnail

고차 컴포넌트(Higher Order Component)는 무엇일까?

리액트 공식 문서에 따르면 고차 컴포넌트는 "컴포넌트 로직을 재사용하기 위한 React의 고급 기술"이라고 표현한다.

쉽게 표현하자면 기존 컴포넌트는 props를 받아 UI를 변환하는 역할을 한다면, 고차 컴포넌트 같은 경우에는 컴포넌트를 가져와 새 컴포넌트를 반환하는 함수이다.

const EnhancedComponent = higherOrderComponent(WrappedComponent);

함수형 고차 컴포넌트 예제

Custom hooks를 만들때 네이밍을 use로 시작하는것과 동일하게 고차 컴포넌트는 with로 시작해준다.

고차 컴포넌트를 활용한 todoList와 userList인지를 판별해 데이터를 넣어주는 함수형 예제로 보자

App.jsx

import './App.css';
import SerachTodos from './components/TodoList';
import SearchUsers from './components/UserList';

function App() {
  return (
    <div className="App">
      <h2>higer order component</h2>
      <div className="section">
        <div>
          <SearchUsers />
        </div>
        <div>
          <SerachTodos />
        </div>
      </div>
    </div>
  );
}

export default App;

withHOC.jsx

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

function withHOC(WrappedComponent, entity) {
  return function () {
    const [data, setData] = useState([]);
    const [term, setTerm] = useState('');

    useEffect(() => {
      const timer = setTimeout(() => {
        let fetchData =
          entity === 'users'
            ? [
                { name: 'yeji', id: 1 },
                { name: 'yoyo', id: 2 },
                { name: 'jojo', id: 3 },
                { name: 'aoao', id: 4 },
              ]
            : [
                { id: 1, userId: 1, title: 'hello', completed: true },
                { id: 2, userId: 2, title: 'bye', completed: true },
                { id: 3, userId: 3, title: 'mornign', completed: false },
                { id: 4, userId: 4, title: 'night', completed: false },
              ];

        setData([...fetchData]);

        clearTimeout(timer);
      }, 2000);
    }, []);

    let filterData = data.filter((d) => {
      if (entity === 'users') {
        const { name } = d;
        return name.indexOf(term) >= 0;
      }

      if (entity === 'todos') {
        const { title } = d;
        return title.indexOf(term) >= 0;
      }
    });

    return (
      <div>
        <h2>{entity}</h2>
        <input
          type="text"
          value={term}
          onChange={(e) => setTerm(e.target.value)}
        />
        <WrappedComponent data={filterData}></WrappedComponent>
      </div>
    );
  };
}

export default withHOC;

TodoList.jsx

import React, { useEffect, useState } from 'react';
import withHOC from './HOC';

function TodoLIst({ data }) {
  let renderTodos = data.map((todo) => {
    return (
      <div key={todo.id}>
        <p>
          <strong>{todo.title}</strong>
        </p>
      </div>
    );
  });

  return (
    <div>
      <div>{renderTodos}</div>
    </div>
  );
}

const SerachTodos = withHOC(TodoLIst, 'todos');

export default SerachTodos;

UserList.jsx

import React, { useEffect, useState } from 'react';
import withHOC from './HOC';

function UserList({ data }) {
  let renderUsers = data.map((user) => {
    return (
      <div key={user.id}>
        <p>
          <strong>{user.name}</strong>
        </p>
      </div>
    );
  });

  return (
    <div>
      <div>{renderUsers}</div>
    </div>
  );
}

const SearchUsers = withHOC(UserList, 'users');

export default SearchUsers;

결론

HOC 패턴은 사실상 React에 hooks라는 개념이 나오기전에 재사용될만한 로직들을 간편하게 정리하기 위해 자주 쓰이던 패턴인듯 하다. 하지만 hooks가 등장하고 재사용 로직들이 많이 정돈되면서 대부분의 경우에서 HOC패턴은 hooks로 대처 가능하게 되었다.

profile
만들고 싶은게 많은 개발자

0개의 댓글