인프런, 유데미/Slack 클론 코딩
커스텀 훅
5_hyun
2022. 7. 16. 18:31
반응형
커스텀 훅
커스텀 훅이란 리액트에서 기본 제공하는 훅을 합쳐서 사용자가 훅을 만드는 것이다. 예를 들어 useState와 useCallback을 합쳐서 새로운 훅을 만들 수 있다.
import { useCallback, useState } from 'react';
const useInput = (initialData) => {
const [value, setValue] = useState(initialData);
const handler = useCallback((e: any) => {
setValue(e.target.value);
}, []);
return [value, handler, setValue];
};
export default useInput;
이런 식으로 useState, useCallback을 합쳐서 한번에 반환해주는 훅을 만들었다.
-훅 적용전 코드
const [email, setEmail] = useState('');
const [nickname, setNickname] = useState('');
const onChangeEmail = useCallback((e: any) => {
setEmail(e.target.value);
}, []);
const onChangeNickname = useCallback((e: any) => {
setNickname(e.target.value);
}, []);
-훅 적용 코드
const [email, onChangeEmail] = useInput('');
const [nickname, onChangeNickname] = useInput('');
중복되는 것을 제거할 수 있다.
훅 더 좋게 쓰는 법들
-type 선언
const useInput = <T = any>(initialData: T): [T, (e: any) => void, Dispatch<SetStateAction<T>>] => {
const [value, setValue] = useState(initialData);
const handler = useCallback((e: any) => {
setValue(e.target.value);
}, []);
return [value, handler, setValue];
};
매개변수에는 타입을 제너릭을 줬다. 그리고 리턴값의 타입은 위에 선언해준다. 하지만 이렇게 ts에서는 가독성이 안좋아질 수도 있다.
-type을 변수로 빼기
import { Dispatch, SetStateAction, useCallback, useState } from 'react';
type ReturnTypes<T = any> = [T, (e: any) => void, Dispatch<SetStateAction<T>>];
const useInput = <T = any>(initialData: T): ReturnTypes<T> => {
const [value, setValue] = useState(initialData);
const handler = useCallback((e: any) => {
setValue(e.target.value);
}, []);
return [value, handler, setValue];
};
export default useInput;
이렇게 하면 가독성은 더 안좋다. 하지만 안전성이 들어난다.
-any 사용하지 않는법
import { ChangeEvent, Dispatch, SetStateAction, useCallback, useState } from 'react';
type ReturnTypes<T = ChangeEvent<HTMLInputElement>> = [
T,
(e: ChangeEvent<HTMLInputElement>) => void,
Dispatch<SetStateAction<T>>,
];
const useInput = <T = ChangeEvent<HTMLInputElement>>(initialData: T): ReturnTypes<T> => {
const [value, setValue] = useState(initialData);
const handler = useCallback((e: ChangeEvent<HTMLInputElement>) => {
setValue(e.target.value as unknown as T);
}, []);
return [value, handler, setValue];
};
export default useInput;
any는 거의 사용하지 않는것이 좋다. 따라서 any 대신 ChangeEvent<HTMLInputElement>를 사용하고 e.target.value 대신 e.target.value as unknown as T를 넣으면 된다.
반응형