A higher-order component (HOC) is an advanced technique in React for reusing component logic. HOCs are not part of the React API, per se. They are a pattern that emerges from React's compositional nature. Concretely, a higher-order component is a function that takes a component and returns a new component.
데이터를 fetch하게 되면, 주로 아래와 같은 패턴이 사용된다. 
function List({ dataStatus }) {
  const { loading, error, data } = dataStatus;
  
  if(loading) return <p>Loading...</p>
  if(Error) return <p>Error occurs!</p>
  return data.map(d => <div>...</div>)
}
한개의 컴포넌트에서 데이터를 fetch한다면, 위와 같은 패턴을 사용하는 것이 문제가 없지만, 여러 컴포넌트에서 useFetch와 같은 커스텀훅을 사용해서 fetch를 한다면, 위의 패턴이 계속 반복된다. 우리는 알고있다. 반복되는 로직을 피해야한다는 것을!
그렇다면 어떻게 효율적으로 반복되는 로직을 줄일 수있을까? 🤓
➡️ HOC을 사용할 수 있다.
HOC을 생성할때는 withSomething과 같은 이름을 사용한다.
WithLoading을 생성
function WithLoading(Component) {
  return function WihLoadingComponent({ dataObj, ...props }) {
    const { loading, error } = dataObj;
    if (loading) return <p>Loading...</p>;
    if (error) return <p>Error</p>;
    return <Component dataObj={dataObj} {...props} />;
  };
}
export default WithLoading;
컴포넌트를 HOC으로 래핑
import List1 from 'components/List1';
import List2 from 'components/List2';
const List1WithLoading = WithLoading(List1);
const List2WithLoading = WithLoading(List2);
function App() {
  useFetch(ACTIVE_STATUS, 'activeStatus');
  useFetch(INFORMATICS, 'informatics');
  
  return(
      <div>
        <List1WithLoading dataObj={data1} title="Informatics" />
        <List2WithLoading dataObj={data2} title="Active Status" />
      </div>
  )
}
위와 같이 useFetch를 반복적으로 사용하고 싶지 않다면, HOC안에 url을 파라미터로 받아서 데이터를 fetch하는 로직을 작성할 수 있다.
withFetch
const withFetch = (WrappedComponent, url) => {
  const [data, setData] = useState([]);
  
  const handleFetch = useCallback(async() => {
    try {
      const res = await fetch(url);
      setData(res.data);
    } catch(error) {
      console.log(error)  
      }
  });
  
  useEffect(() => {
    handleFetch();
  }, [])
 
  return <WrappedComponent data={data}/>
}
export default withFetch;
컴포넌트를 HOC으로 래핑
function List() {
// ...
}
export default withFetch(List, "http://example.com")
import React, { ComponentType } from 'react';
import { Placeholder } from 'styles/styles';
import { DataState } from 'types/types';
interface WithLoadingProps {
  dataObj: DataState;
}
function WithLoading<P extends object>(
  Component: ComponentType<P>
): React.FC<P & WithLoadingProps> {
  return function WihLoadingComponent({ dataObj, ...props }: WithLoadingProps) {
    const { loading, error } = dataObj;
    if (loading) return <Placeholder>Loading...</Placeholder>;
    if (error) return <Placeholder>Error</Placeholder>;
    return <Component dataObj={dataObj} {...(props as P)} />;
  };
}
export default WithLoading;