본문 바로가기
React

커스텀 훅

by asd135 2025. 4. 17.
728x90

커스텀 훅

리액트에서 기본 제공되는 훅 이외에 추가로 필요한 기능을 직접 만들어서 사용,

이름이 use로 시작하고 내부에서 다른 Hook을 호출하는 하나의 자바스크립트 함수

 

커스텀 훅이 필요한 이유

1. 여러 컴포넌트에서 비슷한 상태 관리나 효과 처리 로직이 반복될 때, 커스텀 훅으로 분리하면 중복 코드를 줄일 수 있다.

2. 코드 가독성 및 유지보수성 향상

3. 한 번 만든 커스텀 훅을 여러 컴포넌트에서 사용할 수 있어 생산성이 높아짐

여러 개의 컴포넌트에서 하나의 커스텀 훅을 사용할 때 state는 공유될까?

(X) 커스텀 훅은 단순히 함수일 뿐이며, React 컴포넌트 내부에서 호출될 때마다 독립적인 상태(state)와 효과(effect)를 만든다. 즉 커스텀 훅을 여러 컴포넌트에서 사용해도 각 컴포넌트마다 훅의 상태가 따로 관리된다.

 

왜 상태가 공유되지 않을까?

React 훅(useState, useEffect 등)은 컴포넌트 렌더링 시점에 훅 호출 순서와 위치에 따라 내부적으로 상태를 관리하며, 커스텀 훅도 내부에서 useState같은 훅을 호출하기 때문에, 호출된 컴포넌트마다 독립적인 상태 공간이 만들어짐, 결론은 커스텀 훅은 상태와 로직을 재사용하는 코드이고 상태를 저장하는 전역 저장소가 아니다.

 

import React, {useState} from "react";
// 커스텀 훅 정의
function useCounter() {
    const [count, setCount] = useState(0);
    const increment = ()=> setCount(x=>x+1);
    return {count, increment};
}

// 컴포넌트 A
function A(){
    const { count, increment } = useCounter();
    return (
        <div>
            <p>A: {count}</p>
            <button onClick={increment}>A 버튼</button>
        </div>
    );
}

// 컴포넌트 B
function B() {
    const { count, increment } = useCounter();
    return (
      <div>
        <p>B: {count}</p>
        <button onClick={increment}>B 버튼</button>
      </div>
    );
  }

export { A, B };

 

 

 

 

카운트하는 커스텀 훅

 

useCounter.jsx

import React, {useState} from "react";

function useCounter(init) {
    const [count, setCount] = useState(init);

    const increaseCount = ()=> setCount((count)=>count+1);
    const decreaseCount = ()=> setCount((count)=> Math.max(count-1, 0));

    return [count, increaseCount, decreaseCount];
}
export default useCounter;

Accomodate.jsx

import React, {useState, useEffect} from "react";
import useCounter from "./useCounter";

const MAX_CAPACITY = 10;

function Accomodate(props) {
    const [isFull, setIsFull] = useState(false);
    const [count, increaseCount, decreaseCount] = useCounter(0);

    useEffect(()=>{
        console.log(`isFull: ${isFull}`);
    });

    // count가 변동될 때마다 호출
    useEffect(()=>{
        setIsFull(count >= MAX_CAPACITY); 
        console.log(`Current count value: ${count}`);
    }, [count]);

    return(
        <div style={{padding:16}}>
            <p>{`총 ${count}명 수용`}</p>

            <button onClick={()=>increaseCount()}>입장</button>
            <button onClick={()=>decreaseCount()}>퇴장</button>

            {isFull && <p style={{color:'red'}}>정원이 가득찼습니다.</p>} 
        </div>
    );
}
export default Accomodate;

'React' 카테고리의 다른 글

이벤트 핸들링  (0) 2025.05.29
List와 Key  (0) 2025.05.11
다양한 훅 함수  (0) 2025.04.16
state  (0) 2025.04.09
JSX  (0) 2025.03.26