React

[React] Hooks - customHook

wwxs 2024. 9. 6. 17:29

Custom Hook (커스텀 훅)

  • 리액트의 기본 Hook을 사용하여 작성되는 재사용 가능한 로직의 모음
  • useState, useEffect, useRef 등

Custom Hook 생성 방법

  • use로 시작하는 함수 정의 
  • 해당 함수 내부에서 다른 Hook을 호출
  • 결과와 기능을 반환
더보기
export default function Custom01() {
  const {count, increment, decrement, reset} = useCounter(0)
  
  return (
    <div>
      {count}
      <button onClick={increment}>증가</button>
      <button onClick={decrement}>감소</button>
      <button onClick={reset}>리셋</button>
    </div>
  )
}

 

(예제 코드)

더보기
import React from "react";
import { useInput } from "./useInput";

export default function Custom02() {
  // 커스텀 훅을 사용한 input창 상태 관리
  //# 이름 입력에 대한 관리
  const { 
    value: name, 
    bind: nameBind, // value 데이터 값, onChange 변화 함수
    reset: nameReset 
  } = useInput("");

  //# 이메일 입력에 대한 관리
  const { 
    value: email, 
    bind: emailBind, 
    reset: emailReset 
  } = useInput("");

  //# 닉네임 임력에 대한 관리
  const { 
    value: nickName, 
    bind: nickNameBind, 
    reset: nickNameReset 
  } = useInput("");

  const handleSubmit = () => {
    console.log(`회원가입 완료: `);
    nameReset();
    emailReset();
    nickNameReset();
  };

  // useInput에 대한 호출 마다 새로운 데이터가 상태 관리
  // const [value, setValue] = useState(initialValue);

  // const handleValueChange = (e: React.ChangeEvent<HTMLInputElement>) => {
  //   setValue(e.target.value);
  // } 

  // const reset = () => {
  //   setValue(initialValue);
  // }

  return (
    <div>
      <input
        type="text"
        name="username"
        placeholder="사용자 이름"
        // UI에 바인딩(적혀)되어 실질적으로 프로세스가 구현
        value={nameBind.value}
        onChange={nameBind.onChange}
      />
      <button onClick={nameReset}>이름 초기화</button>
      <input
        type="text"
        name="email"
        placeholder="사용자 이메일"
        {...emailBind}
        // value={emailBind.value}
        // onChange={emailBind.onChange}
      />
      <button onClick={emailReset}>이메일 초기화</button>
      <input
        type="text"
        name="nickName"
        placeholder="사용자 닉네임"
        value={nickNameBind.value}
        onChange={nickNameBind.onChange}
      />
      <button onClick={nickNameReset}>닉네임 초기화</button>

      {/* 사용자 별명(nickName) 입력 창 */}
      {/* 해당 입력 창에 대한 초기화 */}

      <button onClick={handleSubmit}>회원가입</button>
    </div>
  );
}

 

(카운터 증가, 감소, 리셋 예제)

더보기
import { useState } from "react";

//! 커스텀 훅
// >> 사용되는 컴포넌트에 해당 훅의 기능이 정의된 것처럼 동작


export function useCounter (initialValue: number) {
  // 초기값을 매개변수로 받고
  // >> 키운터를 증가, 감소, 초기화 하는 함수와 현재값을 반환
  const[count, setCount] = useState<number>(initialValue);

  const increment = () => setCount(prevCount => prevCount + 1);
  const decrement = () => setCount(prevCount => prevCount - 1);
  const reset = () => setCount(initialValue);

  // 객체
  // : 속성 1, 메서드 3
  return {count, increment, decrement, reset}
}

 

커스텀 훅 제작

  • useInput
  • input창에 입력되는 값을 저장하고 UI의 변경 상태에 따라 데이터의 상태 관리
  • 여러 개의 input 창을 하나의 훅으로 관리
더보기
import { useState } from "react";

// >> input창에 대한 비움 처리 (초기화)
export function useInput(initialValue: string) {
  // useInput에 대한 호출 마다 새로운 데이터가 상태 관리
  const [value, setValue] = useState(initialValue);

  const handleValueChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
    setValue(e.target.value);
  } 

  const reset = () => {
    setValue(initialValue);
  }

  return {
    // 현재의 상태 값
    value,
    // 변화에 대한 이벤트 핸들러
    // handleValueChange,
    // 초기화 함수
    reset,
    // 바인딩 값: UI에 직접적으로 적용될 속성과 함수를 정의
    bind: {
      value,
      onChange: handleValueChange
    }
  }
}