레이블이 useState인 게시물을 표시합니다. 모든 게시물 표시
레이블이 useState인 게시물을 표시합니다. 모든 게시물 표시

2025년 1월 18일 토요일

14 커스텀 훅(Custom Hook) 만들기: 재사용 가능한 훅 설계와 실제 프로젝트 활용 예시

 React에서 훅(Hook)은 상태 관리와 생명주기 관련 기능을 컴포넌트에 적용할 수 있게 해주는 함수입니다. 기본 훅 외에도 개발자가 자신만의 **커스텀 훅(Custom Hook)**을 만들어 재사용 가능한 코드를 작성할 수 있습니다. 이번 글에서는 커스텀 훅을 만드는 방법과 실제 프로젝트에서 어떻게 활용할 수 있는지에 대해 다뤄보겠습니다. 커스텀 훅을 통해 코드의 가독성, 유지보수성, 재사용성을 높이는 방법을 함께 살펴보겠습니다.

커스텀 훅, React 훅, useState, useEffect, React 커스텀 훅, 폼 입력 관리, React 폼, useForm 훅, API 요청 훅, React 코드 재사용


1. 커스텀 훅이란 무엇인가요?

커스텀 훅은 React의 기본 훅을 활용하여 특정 기능을 재사용할 수 있도록 만든 함수입니다. 기본 훅(useState, useEffect, useContext 등)을 조합하여 필요한 로직을 캡슐화하고, 여러 컴포넌트에서 이를 재사용할 수 있도록 해줍니다.

a. 커스텀 훅의 기본 구조

커스텀 훅은 반드시 use로 시작하는 함수명으로 정의해야 합니다. 이는 React에서 훅을 구별하는 규칙입니다. 예를 들어, useFetch라는 훅을 만들어 데이터를 가져오는 기능을 구현할 수 있습니다.


import { useState, useEffect } from 'react'; // 커스텀 훅 예시: useFetch function useFetch(url) { const [data, setData] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { fetch(url) .then((response) => response.json()) .then((data) => { setData(data); setLoading(false); }) .catch((error) => { setError(error); setLoading(false); }); }, [url]); return { data, loading, error }; }

위 코드에서 useFetch는 주어진 url에서 데이터를 가져오는 커스텀 훅입니다. 이 훅은 data, loading, error 상태를 관리하고, 이를 호출한 컴포넌트에서 재사용할 수 있게 해줍니다.


2. 커스텀 훅 만들기: 재사용 가능한 훅 설계

커스텀 훅을 만들 때 중요한 점은 코드의 재사용성을 높이고, 다른 컴포넌트에서 손쉽게 활용할 수 있도록 설계하는 것입니다. 커스텀 훅은 복잡한 로직을 분리하고, 여러 컴포넌트에서 동일한 기능을 반복하지 않도록 돕습니다.

a. 예시: 폼 입력 관리 훅 만들기

사용자가 입력한 값을 관리하는 폼을 여러 곳에서 사용한다면, 이를 관리하는 커스텀 훅을 만들 수 있습니다. 이 훅을 통해 입력 값, 오류 메시지, 폼 검증 로직을 간단하게 처리할 수 있습니다.


import { useState } from 'react'; // 커스텀 훅 예시: useForm function useForm(initialValues) { const [values, setValues] = useState(initialValues); const [errors, setErrors] = useState({}); const handleChange = (e) => { const { name, value } = e.target; setValues({ ...values, [name]: value, }); }; const validate = () => { let formErrors = {}; if (!values.name) { formErrors.name = '이름을 입력해주세요'; } if (!values.email) { formErrors.email = '이메일을 입력해주세요'; } setErrors(formErrors); return formErrors; }; return { values, errors, handleChange, validate, }; }

위 예시에서 useForm 훅은 name, email 등의 필드를 가진 폼의 입력 값을 관리하고, 입력 값이 비어 있을 경우 오류 메시지를 반환합니다. useForm 훅을 사용하면 여러 폼에서 같은 로직을 반복하지 않고, 코드의 중복을 줄일 수 있습니다.

b. 커스텀 훅을 사용한 컴포넌트 활용

커스텀 훅은 실제 컴포넌트에서 어떻게 활용될까요? 아래 예시에서는 useForm 훅을 활용하여 간단한 회원 가입 폼을 구현해 보겠습니다.


import React from 'react'; import { useForm } from './useForm'; // useForm 훅 임포트 function SignUpForm() { const { values, errors, handleChange, validate } = useForm({ name: '', email: '' }); const handleSubmit = (e) => { e.preventDefault(); const formErrors = validate(); if (Object.keys(formErrors).length === 0) { // 폼 제출 처리 로직 console.log('폼 제출:', values); } }; return ( <form onSubmit={handleSubmit}> <div> <label>이름:</label> <input type="text" name="name" value={values.name} onChange={handleChange} /> {errors.name && <p>{errors.name}</p>} </div> <div> <label>이메일:</label> <input type="email" name="email" value={values.email} onChange={handleChange} /> {errors.email && <p>{errors.email}</p>} </div> <button type="submit">회원 가입</button> </form> ); } export default SignUpForm;

SignUpForm 컴포넌트에서는 useForm 훅을 사용하여 폼 상태와 검증을 처리하고 있습니다. 이렇게 하면 폼 관련 로직을 useForm 커스텀 훅에서 분리하여 재사용할 수 있습니다.


3. 커스텀 훅을 실제 프로젝트에서 활용하기

커스텀 훅은 복잡한 상태 관리나 공통 기능을 처리할 때 유용합니다. 예를 들어, API 호출, 폼 입력 처리, 애니메이션 상태 관리 등 다양한 상황에서 커스텀 훅을 활용할 수 있습니다.

a. 예시: API 요청을 처리하는 커스텀 훅

여러 컴포넌트에서 같은 API를 호출해야 하는 경우, 이를 하나의 커스텀 훅으로 만들 수 있습니다. 예를 들어, 데이터 목록을 가져오는 useFetchList 훅을 만들 수 있습니다.


import { useState, useEffect } from 'react'; function useFetchList(url) { const [list, setList] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { fetch(url) .then((response) => response.json()) .then((data) => { setList(data); setLoading(false); }) .catch((error) => { setError(error); setLoading(false); }); }, [url]); return { list, loading, error }; }

useFetchList 훅을 여러 컴포넌트에서 재사용하여 데이터 목록을 가져오고 처리할 수 있습니다. 커스텀 훅을 사용함으로써 코드의 중복을 줄이고, 유지보수성을 높일 수 있습니다.


4. 결론

커스텀 훅을 사용하면 React 애플리케이션의 코드가 더 간결하고 재사용 가능하게 됩니다. useState, useEffect 등의 기본 훅을 활용해 상태 관리나 로직을 캡슐화하고, 이를 여러 컴포넌트에서 재사용할 수 있습니다. 또한, 커스텀 훅을 통해 코드의 유지보수성과 가독성을 향상시킬 수 있습니다.

**커스텀 훅(Custom Hook)**은 특히 복잡한 로직을 여러 컴포넌트에서 공유하고자 할 때 매우 유용합니다. 이를 통해 더 깔끔하고 효율적인 React 애플리케이션을 개발할 수 있습니다.

10 React에서 폼(Form) 다루기: 입력 요소의 상태 관리 및 useRef 활용

 

React 폼, 제어 컴포넌트, 비제어 컴포넌트, useState, useRef, React 상태 관리, 폼 입력, React 이벤트 처리, 폼 제출, React 렌더링



1. React에서 폼(Form)의 중요성

웹 애플리케이션에서 폼(Form)은 사용자 입력을 받아 처리하는 중요한 요소입니다. React에서는 폼을 다룰 때 제어 컴포넌트(Control Component)와 비제어 컴포넌트(Uncontrolled Component)라는 두 가지 방식이 있습니다. 이번 글에서는 입력 요소의 상태 관리와 useRef를 활용한 비제어 컴포넌트를 살펴보겠습니다.

2. 입력 요소의 상태 관리

입력 요소의 상태를 관리하는 가장 일반적인 방법은 useState를 사용하는 것입니다. useState를 활용하면 입력 값이 변경될 때마다 상태를 업데이트할 수 있습니다.

가. useState를 활용한 입력 요소 관리

import React, { useState } from "react";

function ControlledForm() {
  const [name, setName] = useState("");

  const handleChange = (event) => {
    setName(event.target.value);
  };

  const handleSubmit = (event) => {
    event.preventDefault();
    alert(`입력된 이름: ${name}`);
  };

  return (
    <form onSubmit={handleSubmit}>
      <input type="text" value={name} onChange={handleChange} />
      <button type="submit">제출</button>
    </form>
  );
}

export default ControlledForm;

위 코드에서 useState를 활용하여 name 상태를 관리하고 있으며, 입력 값이 변경될 때마다 onChange 이벤트를 통해 상태를 업데이트합니다.

3. useRef를 활용한 비제어 컴포넌트

비제어 컴포넌트는 useRef를 활용하여 직접 DOM 요소에 접근하여 값을 가져오는 방식입니다. 상태 관리를 하지 않기 때문에 불필요한 렌더링을 줄일 수 있습니다.

나. useRef를 활용한 비제어 컴포넌트 예제

import React, { useRef } from "react";

function UncontrolledForm() {
  const inputRef = useRef(null);

  const handleSubmit = (event) => {
    event.preventDefault();
    alert(`입력된 값: ${inputRef.current.value}`);
  };

  return (
    <form onSubmit={handleSubmit}>
      <input type="text" ref={inputRef} />
      <button type="submit">제출</button>
    </form>
  );
}

export default UncontrolledForm;

위 코드에서 useRef를 활용하여 입력 요소에 직접 접근하고 있으며, onChange 이벤트 없이도 값을 가져올 수 있습니다.

4. 제어 컴포넌트 vs 비제어 컴포넌트

비교 항목제어 컴포넌트 (Controlled)비제어 컴포넌트 (Uncontrolled)

상태 관리useState 활용useRef 활용
렌더링 발생값 변경 시마다 리렌더링값 변경 시 리렌더링 없음
활용 예동적 검증, 실시간 입력 값 처리빠른 폼 제출, 초기값 유지

제어 컴포넌트는 입력 값이 상태에 저장되므로 입력 값 검증이나 조건부 로직 적용에 유용합니다. 반면, 비제어 컴포넌트는 입력 값을 한 번에 가져와야 할 때 유용하며, 불필요한 리렌더링을 방지할 수 있습니다.

5. 정리

React에서 폼을 다루는 방식에는 제어 컴포넌트와 비제어 컴포넌트가 있으며, 각각의 장점과 단점이 존재합니다. useState를 사용하면 입력 값을 쉽게 관리할 수 있지만, 렌더링 비용이 증가할 수 있습니다. 반면, useRef를 활용한 비제어 컴포넌트는 렌더링을 최소화할 수 있지만 값 변경을 실시간으로 반영하기 어렵습니다.

React에서 폼을 다룰 때 프로젝트의 요구 사항에 맞게 적절한 방법을 선택하는 것이 중요합니다. 앞으로의 개발에서 이 두 가지 방식을 적절히 활용하여 효율적인 폼 관리를 해보시길 바랍니다!