[TIL 221125] HOC

ponyo·2022년 11월 25일
0

Today I Learned

목록 보기
1/30

HOC: Higher Order Component ( 고차 컴포넌트 )

고차 컴포넌트는 컴포넌트를 가져와 새 컴포넌트를 반환하는 함수

React 공식 문서

구현하고자 하는 것

Button ComponentInput Component가 로딩 중에는 <p>Loading...</p> 가 그려지고 화면이 렌더링되고 3초 후에 로딩이 완료되면서 Button ComponentInput Component 가 각각 buttoninput으로 그려진다.

공통 기능 재사용

Button ComponentInput Component는 로딩 중이라는 p태그를 그리고 3초 후에 각각의 element를 그리는 공통된 기능을 가지고 있다.

Custom hook을 사용해도 되지만 이 예제의 경우 HOC를 사용해서 구현해보자!!

coding 과정

우선 HOC 없이 각각의 component에 해당 기능을 구현하는 코드를 적어보자 !

Button.jsx

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

const Button = () => {
  const [loading, setLoading] = useState(true);
  
  useEffect(() => {
    // clearTimeout을 하기위해 무기명함수가 아닌 기명함수로 선언
  	const timer = setTimeout(() => setLoading(false), 3000);
    
    return () => clearTimeout(timer); // 구독 해지
  }, []);
  return loading ? <p>Loading...</p> : <button>button</button>;
}

export default Button;

Input.jsx

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

const Input = () => {
  const [loading, setLoading] = useState(true);
  
  useEffect(() => {
    // clearTimeout을 하기위해 무기명함수가 아닌 기명함수로 선언
  	const timer = setTimeout(() => setLoading(false), 3000);
    
    return () => clearTimeout(timer); // 구독 해지
  }, []);
  return loading ? <p>Loading...</p> : <input type="text"/>;
}

export default Input;

HOC를 사용한 Refactorying

🚀 위 컴포넌트들은 공통된 기능을 사용하고 있으므로 HOC를 사용하여 새 컴포넌트들을 반환하자

우선 withLoading.jsx 파일을 만들고 아래처럼 withLoading 함수를 정의하자

withLoading.jsx

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

export default const withLoading(component) => { // 함수기 때문에 대문자가 아닌 소문자로 표현
  const WithLoadingComponent = (props) => {
    const [loading, setLoading] = useState(true);
    
    useEffect(() => {
      // clearTimeout을 하기위해 무기명함수가 아닌 기명함수로 선언
      const timer = setTimeout(() => setLoading(false), 3000);
      
      return () => clearTimeout(timer);
    }, []);
    
    return loading ? <p>Loading...</p> : <Component />;
  };
  
  return WithLoadingComponent;
}

Button.jsx

import React from 'react'
import withLoading from './withLoading';

function Button() {
  return <button>Button</button>
}

export default withLoading(Button);

Input.jsx

import React from 'react'
import withLoading from './withLoading'

const Input = () => {
  return <input type="text" />
}

export default withLoading(Input);

💡 React.memo도 HOC (고차함수) 이다.

profile
😁

0개의 댓글