반응형
Notice
Recent Posts
Recent Comments
Link
관리 메뉴

짧은코딩

커스텀 훅 본문

인프런, 유데미/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를 넣으면 된다.

반응형
Comments