커스텀 훅(Custom Hook)은 리액트 함수 컴포넌트에서 상태 관리, 사이드 이펙트 처리 등을 추상화하여 재사용 가능한 로직 단위로 만들어진 것이다. 이를 통해 코드 중복을 줄이고 가독성을 높이며, 복잡한 컴포넌트를 간결하게 유지할 수 있다.
커스텀 훅을 만들어서 반복되는 로직을 재사용하는 방법을 알아본다.
num1과 num2 라는 변수가 있는데 이 두 변수의 값을 방향키로 1씩 증가시키거나 감소시키는 기능을 만들려고 한다. 어떤 변수를 조작할 것인지 선택하는 버튼이 있어서 이 버튼을 클릭할 때마다 조작하는 변수를 전환한다.
useKey.tsx
import {
useState,
useEffect,
useCallback,
Dispatch,
SetStateAction,
} from "react";
function useKey(targetValSetter: Dispatch<SetStateAction<number>>) {
const handleKeyDown = useCallback(
(event: KeyboardEvent) => {
if (event.key === "ArrowUp") {
targetValSetter((prevVal: number) => {
return prevVal + 1;
});
} else if (event.key === "ArrowDown") {
targetValSetter((prevVal: number) => {
return prevVal - 1;
});
}
},
[targetValSetter]
);
useEffect(() => {
document.addEventListener("keydown", handleKeyDown);
return () => {
document.removeEventListener("keydown", handleKeyDown);
};
}, [handleKeyDown]);
}
export default useKey;
target 변수의 setter 함수를 인자로 받아서 이벤트가 일어나면 인자로 받은 setter 함수를 실행시킨다.
App.tsx
import { useState } from "react";
import "./App.css";
import useKey from "./useKey";
function App() {
const [num1, setNum1] = useState<number>(0);
const [num2, setNum2] = useState<number>(0);
const [curNum, setCurNum] = useState<boolean>(true);
useKey(curNum === true ? setNum1 : setNum2);
const highlight = "border border-red-500 rounded-md p-2 m-2 text-center";
const handleClick = () => {
curNum ? setCurNum(false) : setCurNum(true);
};
return (
<div className="flex flex-col items-center">
<div className="grid grid-cols-1 p-2 w-36 justify-items-center">
<p className={curNum ? highlight : "p-2 text-center m-2"}>
num1 : {num1}
</p>
<p className={!curNum ? highlight : "p-2 text-center m-2"}>
num2 : {num2}
</p>
<button
className="bg-slate-200 rounded-md p-2 text-center w-12 "
onClick={handleClick}
>
전환
</button>
</div>
</div>
);
}
export default App;
num1과 num2 두 변수를 선언하고 현재 조작하는 변수의 상태를 저장하는 curNum 변수를 선언하였다. curNum이 true면 num1을 조작하고 false면 num2를 조작한다. 실행화면을 알아보기 쉽게 tailwind로 css를 추가하였다.
useState의 setter함수의 타입을 어떻게 해야 할지 모를수도 있는데 그냥 아무 값이나 넣고 나오는 오류메시지에서 복사해 넣으면 된다. useKey 훅을 호출하는 부분에서 인자에 0을 넣고 나오는 오류메시지에 타입이 나온다.
이벤트 핸들러 함수를 useCallback으로 메모이제이션했다면 의존성 배열에 주의해야 한다. 인자로 받은 setter 함수가 변경되면 함수를 재생성하고 재생성된 함수를 이벤트 리스너에 다시 등록해야 하기 때문이다.
useCallback의 의존성 배열이 없으면 함수가 재생성되지 않아서 num1의 setter만 계속 사용된다.
useEffect의 의존성 배열이 없으면 이벤트 리스너에 함수가 재등록되지 않아 처음에 등록된 이벤트 핸들러만 계속 사용된다.
'리액트,타입스크립트' 카테고리의 다른 글
리액트에서 tailwind css 사용하기 (0) | 2024.02.23 |
---|---|
타입스크립트 axios로 파일다운로드 구현하기 (0) | 2024.01.21 |
타입스크립트 리덕스 사용하기 (0) | 2024.01.08 |
리액트 타입스크립트 시작하기 (0) | 2024.01.08 |
리액트에서 구글맵 현재위치 마커 찍기 (0) | 2022.11.01 |