Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
Tags
- 항해99
- 실전프로젝트
- server component
- 그리디
- 카테고리필터
- 백준
- 클라이언트 컴포넌트
- 서버 컴포넌트
- 항해99추천
- db수정
- 자바스크립트
- 동전 0
- 숫자를 별점으로
- 배열 메소드
- 항해99솔직후기
- 프로그래머스
- 항해99후기
- 날씨 api
- JavaScript
- 알고리즘
- greedy
- 배열 중복 제거
- jQuery
- 탐욕알고리즘
- react
- 중복카테고리
- 로딩 후 실행
- NextJS v13
- 부트캠프항해
- 중복선택
Archives
- Today
- Total
공부 및 일상기록
[React] HOC에 대해 설명 본문
고차컴포넌트 (HOC, Higher order component)는 컴포넌트 로직을 재사용하기 위한 React의 고급 기술이다. 고차 컴포넌트는 React API의 일부가 아니며, React의 구성적 특성에서 나오는 패턴이다.
고차컴포넌트는 컴포넌트를 가져와 새 컴포넌트를 반환하는 함수이다.
주의사항
- render메서드 안에서 고차컴포넌트를 사용하면 안된다.
- 컴포넌트의 정의 바깥에 HOC를 적용하여 컴포넌트가 한번만 생성되어야 한다.
- 정적 메서드는 반드시 따로 복사해야 한다.
- 메서드를 반환하기 전에 컨테이너에 복사한다.
- hoist-non-react-statics를 사용하여 모든 non-React 정적 메서드를 자동으로 복사한다.
- 정적 메서드를 컴포넌트와 별도로 내보낸다.
- ref는 전달되지 않는다.
- React.forwardRef API를 사용한다.
사용방법
HOC는 with로 시작하는 컨벤션으로 파일을 작성한다.
먼저 예제로 작성할 코드를 보자
1. App.js가 다음과 같이 존재한다.
import Input from './components/Input'
import Button from './components/Button'
function App() {
return (
<>
<Input /><br />
<Button />
</>
);
}
2. Button컴포넌트는 다음과 같다.
import { useState, useEffect } from 'react';
// Loading 3초 후 button이 보이는 Button 컴포넌트
export default function Button() {
const [loading, setLoading] = useState(true);
useEffect(() => {
const timer = setTimeout(() => setLoading(false), 3000);
return () => clearTimeout(timer);
}, []);
return loading ? <span>Loading...</span> : <button>Button</button>;
}
3. Input컴포넌트는 다음과 같다.
import { useState, useEffect } from 'react';
// Loading 3초 후 input이 보이는 Input 컴포넌트
export default function Input() {
const [loading, setLoading] = useState(true);
useEffect(() => {
const timer = setTimeout(() => setLoading(false), 3000);
return () => clearTimeout(timer);
}, []);
return loading ? <span>Loading...</span> : <input defaultValue="Input" />;
}
자세히 읽다보면 button과 input은 동일한 역할을 수행하는 부분이 있다.
바로 loading 시간을 3초 기다리고 그동안은 loading을 보여주는 것이다.
따라서 아래와 같이 withLoading 이라는 컴포넌트로 묶어 낼 수 있다.
import { useState, useEffect } from 'react';
export default function withLoading(Component) {
const WithLoadingComponent = (props) => {
const [loading, setLoading] = useState(true);
useEffect(() => {
const timer = setTimeout(() => setLoading(false), 3000);
return () => clearTimeout(timer);
}, []);
return loading ? <span>Loading...</span> : <Component {...props} />;
};
return WithLoadingComponent;
그럼 이제 묶어내었으므로 버튼과 인풋의 코드도 바뀌어야 한다.
import withLoading from './withLoading';
function Button() {
return <button>Button</button>;
}
export default withLoading(Button);
import withLoading from './withLoading';
function Input() {
return <input defaultValue="Input" />;
}
export default withLoading(Input);
위처럼 중복된 코드를 제거해내고 export default에 withLoading(해당컴포넌트) 를 넣어서 동작하면 동작이 잘 된다.
'개발 > React' 카테고리의 다른 글
[React] Memoization (0) | 2023.01.17 |
---|---|
[React] React.Fragment (0) | 2023.01.17 |
[React] context API (0) | 2023.01.12 |
[React] html과 리액트의 이벤트 처리 방식 차이점 (0) | 2023.01.12 |
[React] map함수 사용시 key props를 사용해야 하는 이유 (2) | 2023.01.12 |