custom HOC
- 재사용 가능한 로직을 분리해서 컴포넌트 사이에서 공유한다.
- 불필요한 추상 레이어(컴포넌트 래퍼)를 생성한다.
- 클래스, 함수 컴포넌트 모두 사용 가능
- 커스텀 HOC를 작성할 때는 관례적으로 with 접두사로 이름이 시작되지만, 절대적 규칙은 아님
ex) React.memo(Component)
custom Hook
- 재사용 가능한 로직을 분리해서 컴포넌트 사이에서 공유한다.
- 불필요한 추상 레이어(컴포넌트 래퍼)를 생성하지 않는다.
- 오직 함수 컴포넌트 모두 사용 가능
- 훅의 규칙을 반드시 따라야 함 (함수 컴포넌트 또는 커스텀 훅 안에서만 사용 가능)
- 커스텀 훅을 작성할 때는 반드시 use 접두사로 이름이 시작되어야 한다.
ex) React.useMemo(() => <Component />)
토글 상태 관리 커스텀 훅
import { useCallback, useState } from 'react';
/**
* 토글 상태 관리 커스텀 훅
* @param {boolean} initialToggleState 최초의 토글 상태 값
* @returns {{ toggle: boolean; onToggle: () => void; offToggle: () => void; }}
*/
export function useToggle(initialToggleState = false) {
const [toggle, setToggle] = useState(initialToggleState);
const onToggle = useCallback(() => setToggle(true), []);
const offToggle = useCallback(() => setToggle(false), []);
return { toggle, onToggle, offToggle };
}
사용자의 마우스 x, y 위치 값을 반환하는 React 커스텀 훅
// import { debounce } from '@/utils';
//* lodash library 사용
import debounce from 'lodash.debounce';
import { useState, useEffect } from 'react';
/**
* 사용자의 마우스 x, y 위치 값을 반환하는 React 커스텀 훅
* @returns {{ x: number, y: number }} 마우스 x, y 위치
*/
export function useMouse(recordTime = 300) {
const [x, updateX] = useState(0);
const [y, updateY] = useState(0);
useEffect(() => {
const EVENT_TYPE = 'mousemove';
const handleMouseMove = debounce((e) => {
updateX(e.pageX);
updateY(e.pageY);
}, recordTime);
// 이벤트 구독
globalThis.addEventListener(EVENT_TYPE, handleMouseMove);
//이벤트 구독 해지
return () => {
globalThis.addEventListener(EVENT_TYPE, handleMouseMove);
};
}, []);
return { x, y }; // {x:0, y:0}
}
fetch 훅
import axios from 'axios';
import { useEffect, useState } from 'react';
export function useFetch(endpoint) {
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState(null);
const [data, setData] = useState(null);
useEffect(() => {
async function fetchData() {
//axios
try {
const { data } = await axios.get(endpoint);
setData(data);
} catch (error) {
setError(error);
} finally {
setIsLoading(false);
}
}
fetchData();
}, [endpoint]);
return { isLoading, error, data };
}
문서 제목 변경 React 커스텀 훅
import { useLayoutEffect } from 'react';
// 사용자 정의 훅
// use 접두사를 사용하는 함수
// 웹 문서의 제목을 변경하는 훅
// 사이드 이펙트
/**
* 문서 제목 변경 React 커스텀 훅
* @param {string} titleContent 웹 문서 제목
*/
export const useDocumentTitle = (titleContent) => {
useLayoutEffect(() => {
document.title = titleContent;
}, [titleContent]);
};
Counter React 커스텀 훅
import { useState, useEffect } from "react";
export const useCounter = (forwards = true) => {
const [counter, setCounter] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
if (forwards) {
setCounter((prevCounter) => prevCounter + 1);
} else {
setCounter((prevCounter) => prevCounter - 1);
}
}, 1000);
return () => clearInterval(interval);
}, [forwards]);
return counter;
};
참고 사이트
https://ko.reactjs.org/docs/hooks-overview.html#building-your-own-hooks
https://beta.reactjs.org/learn/reusing-logic-with-custom-hooks
'React' 카테고리의 다른 글
Recoil 기본 개념 (1) | 2023.03.31 |
---|---|
리액트 라우터 outlet 사용하여 중첩된 레이아웃 구성 (0) | 2023.03.09 |
useState & useEffect 비교 (0) | 2023.03.01 |
React Portal이란? (0) | 2023.03.01 |
DOM(돔) vs Virtual DOM(가상 돔) (0) | 2023.02.14 |