React – 상태 관리와 Hooks – 커스텀 Hooks – 2 – 실제 예시: useInput, useFetch 등

React – 상태 관리와 Hooks – 커스텀 Hooks – 2 – 실제 예시: useInput, useFetch 등

React – 상태 관리와 Hooks – 커스텀 Hooks – 2 – 실제 예시: useInput, useFetch 등

안녕하세요 여러분 😊
이번 시간에는 React에서 정말 유용하게 쓸 수 있는 커스텀 훅의 실전 예시들을 하나하나 살펴보려고 해요!

이론은 알겠는데 실제로 어디서 어떻게 써야 할지 감이 잘 안 잡히셨죠?
그래서 오늘은 바로 복사해서 쓸 수 있을 만큼 실용적인 예시들을 소개해 드릴게요!

“훅”이라는 단어는 마치 낚시바늘처럼 필요한 데이터를 콕! 집어오듯,
커스텀 훅은 여러분의 컴포넌트에 필요한 로직을 정확히 가져오는 마법의 도구랍니다! 🎣


1. useInput – 입력 상태를 간단하게 관리

✨ 기능 설명

useState, onChange 핸들러, 초기화 등을 모두 포함한 입력 필드 전용 훅입니다.

📦 훅 구현

import { useState } from 'react';

function useInput(initialValue = '') {
  const [value, setValue] = useState(initialValue);

  const onChange = (e) => setValue(e.target.value);
  const reset = () => setValue(initialValue);

  return { value, onChange, reset };
}

🧪 사용 예시

function LoginForm() {
  const username = useInput('');
  const password = useInput('');

  const handleSubmit = () => {
    alert(`ID: ${username.value}, PW: ${password.value}`);
    username.reset();
    password.reset();
  };

  return (
    <div>
      <input placeholder="아이디" {...username} />
      <input placeholder="비밀번호" type="password" {...password} />
      <button onClick={handleSubmit}>로그인</button>
    </div>
  );
}

🎁 마치 useStateonChange를 하나로 랩핑한 미니훅이에요!
Form 입력 필드가 많을수록 이 훅이 빛을 발한답니다!


2. useFetch – API 데이터 받아오기

✨ 기능 설명

fetch를 이용한 데이터 요청, 로딩 상태, 에러 핸들링까지 자동으로 처리해주는 훅이에요.

📦 훅 구현

import { useState, useEffect } from 'react';

function useFetch(url) {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    if (!url) return;

    setLoading(true);
    fetch(url)
      .then((res) => {
        if (!res.ok) throw new Error('네트워크 오류');
        return res.json();
      })
      .then((json) => {
        setData(json);
        setError(null);
      })
      .catch((err) => {
        console.error(err);
        setError(err);
      })
      .finally(() => setLoading(false));
  }, [url]);

  return { data, loading, error };
}

🧪 사용 예시

function UserList() {
  const { data, loading, error } = useFetch('https://jsonplaceholder.typicode.com/users');

  if (loading) return <p>로딩 중...</p>;
  if (error) return <p>에러 발생: {error.message}</p>;

  return (
    <ul>
      {data.map((user) => <li key={user.id}>{user.name}</li>)}
    </ul>
  );
}

📌 컴포넌트가 깨끗해지고, 중복된 API 로직을 재사용할 수 있어요!


3. useToggle – 불리언 상태 토글

✨ 기능 설명

truefalse 상태를 간단하게 전환하고 싶을 때 사용합니다.

📦 훅 구현

import { useState } from 'react';

function useToggle(initial = false) {
  const [state, setState] = useState(initial);

  const toggle = () => setState((prev) => !prev);
  const setTrue = () => setState(true);
  const setFalse = () => setState(false);

  return [state, toggle, setTrue, setFalse];
}

🧪 사용 예시

function ToggleExample() {
  const [visible, toggleVisible] = useToggle();

  return (
    <div>
      <button onClick={toggleVisible}>
        {visible ? '숨기기' : '보이기'}
      </button>
      {visible && <p>여기 내용이 보여요!</p>}
    </div>
  );
}

✅ 모달, 메뉴, 드롭다운 등 다양한 UI에서 활용 가능!


4. useDebounce – 입력값 지연 처리

✨ 기능 설명

검색창 등에 입력 중 실시간 요청을 막고, 입력이 멈춘 후 일정 시간 뒤에 처리하도록 만드는 훅이에요.

📦 훅 구현

import { useState, useEffect } from 'react';

function useDebounce(value, delay = 500) {
  const [debounced, setDebounced] = useState(value);

  useEffect(() => {
    const handler = setTimeout(() => setDebounced(value), delay);
    return () => clearTimeout(handler);
  }, [value, delay]);

  return debounced;
}

🧪 사용 예시

function SearchBox() {
  const [keyword, setKeyword] = useState('');
  const debouncedKeyword = useDebounce(keyword, 1000);

  useEffect(() => {
    if (debouncedKeyword) {
      console.log('검색 요청:', debouncedKeyword);
      // fetch API 요청 가능
    }
  }, [debouncedKeyword]);

  return (
    <input
      placeholder="검색어를 입력하세요"
      value={keyword}
      onChange={(e) => setKeyword(e.target.value)}
    />
  );
}

🔍 사용자의 입력이 멈췄을 때만 요청! 성능 최적화에 굿!


5. useOutsideClick – 외부 클릭 감지 (모달 등에서 유용)

✨ 기능 설명

특정 요소 외부를 클릭하면 특정 동작을 실행하고 싶을 때 사용합니다.

📦 훅 구현

import { useEffect } from 'react';

function useOutsideClick(ref, callback) {
  useEffect(() => {
    const handleClick = (e) => {
      if (ref.current && !ref.current.contains(e.target)) {
        callback();
      }
    };

    document.addEventListener('mousedown', handleClick);
    return () => document.removeEventListener('mousedown', handleClick);
  }, [ref, callback]);
}

🧪 사용 예시

function Modal({ onClose }) {
  const modalRef = useRef(null);
  useOutsideClick(modalRef, onClose);

  return (
    <div ref={modalRef} className="modal">
      <p>모달 내용입니다!</p>
    </div>
  );
}

🎯 모달, 드롭다운, 툴팁 등에서 외부 클릭으로 닫기 기능을 쉽게 구현할 수 있어요!


✅ 마무리 요약표

훅 이름 기능 요약 활용 예시
useInput 입력값 상태 + onChange + 초기화 로그인, 회원가입 폼 등
useFetch API 요청 + 로딩 + 에러 처리 리스트, 상세 페이지 등
useToggle true/false 상태 전환 모달, 사이드바, 드롭다운 등
useDebounce 입력값 디바운싱 처리 검색창, 실시간 입력 최적화
useOutsideClick 외부 클릭 감지 모달, 드롭다운 닫기 등

🚧 주의사항

항목 설명
조건문 안에서 훅 사용 금지 항상 같은 순서로 호출돼야 해요
이름은 반드시 use로 시작 React가 훅으로 인식하게 하기 위함
너무 많은 기능을 하나에 몰지 않기 각 훅은 목적이 분명해야 관리가 쉬워요

🏁 마무리하며

이제 여러분은 실전에서 바로 활용할 수 있는 커스텀 훅들을 여러 개 마스터하셨어요!
이 훅들을 잘 모아두면, 마치 자신만의 React 라이브러리를 만들어가는 느낌이 든답니다 😊

복잡한 로직도 깔끔하게!
중복되는 코드도 간결하게!
커스텀 훅으로 효율적이고 읽기 쉬운 코드를 만들어보세요! 💪

다음 시간엔 커스텀 훅을 다른 훅과 조합해서 더 복잡한 동작을 처리하는 고급 활용법을 소개해 드릴게요!
기대해주세요! 🚀💙

답글 남기기