HOC: Higher Order Component ( 고차 컴포넌트 )
고차 컴포넌트는 컴포넌트를 가져와 새 컴포넌트를 반환하는 함수
Button Component
와 Input Component
가 로딩 중에는 <p>Loading...</p>
가 그려지고 화면이 렌더링되고 3초 후에 로딩이 완료되면서 Button Component
와 Input Component
가 각각 button
과 input
으로 그려진다.
Button Component
와 Input Component
는 로딩 중이라는 p태그를 그리고 3초 후에 각각의 element를 그리는 공통된 기능을 가지고 있다.
Custom hook을 사용해도 되지만 이 예제의 경우 HOC를 사용해서 구현해보자!!
우선 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를 사용하여 새 컴포넌트들을 반환하자
우선 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 (고차함수) 이다.