티스토리 뷰

React

[React] Hook, useState, useEffet

예둥 2025. 1. 3. 16:31

훅(Hook)은 React에서 함수형 컴포넌트(functional componet)에서도 상태(state)와 생명 주기(lifecycle) 기능을 사용할 수 있게 해주는 특별한 함수입니다. Reack 16.8에서 도입되었으며, 기존의 클래스형 컴포넌트로만 가능했던 작업을 훨씬 간결하게 구현할 수 있게 한다.

  1. 함수형 컴포넌트에서 사용 가능 : 클래스형 컴포넌트를 사용하지 않아도 상태 관리, 생명 주기 관련 작업을 처리할 수 있음.
  2. 함수 기반 : 이름이 항상 use로 시작하며, React 내부의 특정 기능과 연결됨.
  3. 재사용 가능 : 사용자 정의 훅을 만들어 코드 재사용성을 높일 수 있음.
  4. 클린한 코드 : 상태와 관련된 로직을 더 명확하고 모듈화된 방식으로 작성 가능.

useState : 상태 관리 훅

  • 함수형 컴포넌트에서 상태(state)를 추가할 수 있게 한다.
  • 상태란 컴포넌트에서 동적으로 변경되는 데이터를 의미한다.

사용법

const [state, setState] = useState(initialValue);
  • state : 현재 상태값.
  • setState : 상태를 업데이트하는 함수. 호출하면 컴포넌트가 다시 렌더링된다.
  • initialValue : 상태의 초기값.

예제 : 간단한 카운터

import React, { useState } from 'react';

function Counter() {
	const [counst, setCount] = useState(0) // 초기값으로 0
    
    const increment = () => {
    	setCount(count + 1); // 상태값 변경
    };
    
    return (
    	<div>
            <p>Count: {count}</p>
            <button onClick={increment}>Increase</button>
        </div>
    );
}

 

핵심 포인트

  1. useState(0)은 count의 초기값을 0으로 설정한다.
  2. setCount를 호출하면 상태값이 변경되고, 컴포넌트가 다시 렌더링된다.

useEffect : 부수 효과(side effect) 관리 훅

  • 컴포넌트가 마운트될 때(처음 dom에 렌더링될 때), 의존성 배열의 값이 변경될 때 실행
  • 부수 효과 예 : dom 조작, 데이터 가져오기(api 호출), 타이머 설정, 구독(subscription) 설정/해제

사용법

useEffect(() => {
	// 부수 효과 작업
    return () => {
    	// 정리(clean-up) 작업 (옵션)
    };
}, [dependency]);
  • 첫 번째 인수 ( () => {...} ) : 부수 효과를 정의하는 함수.
    • 리액트는 이 함수를 기억 했다가 dom 업데이트 후 불러낸다.
    • 함수를 return 할 경우 컴포넌트가 unmount 될 때 다시 한 번 실행된다.
  • 두 번째 인수 ( [dependency] ) : 의존성 배열. 컴포넌트가 mount 될 때, 특정 값이 변경될 때만 효과를 다시 실행.
    • 빈 배열( [] )을 설정하면 컴포넌트가 마운트될 때 한 번만 실행.
    • 배열을 설정하면 컴포넌트가 마운트될 때와 배열에 포함된 값이 변경될 때 실행.

예제 : 컴포넌트 마운트 시 한 번 실행

import React, { useEffect } from 'react';

function App() {
	useEffect(() => {
    	console.log('컴포넌트가 마운트되었습니다.')
    }, []); // 빈 배열 : 마운트 시 한 번만 실행.
    
    retrun <div>Hello, World!</div>;
}

 

예제 : 상태값 변경에 반응

import React, { useState, useEffect } from 'react';

function Counter() {
	const [count, setCount] = useState(0); // 초기값으로 0
    
    useEffect(() => {
    	console.log('Count가 ${count}로 변경되었습니다.')
    }, [count]); // count가 변경될 때만 실행
    
    return (
    	<div>
            <p>Count: {count}</p>
            <button onClick={() => setCount(count + 1)}>Increase</button>
        </div>
    );
}

 

예제 : 정리 작업 (clean-up)

import React, { useState, useEffect } from 'react';

function Timer() {
	const [seconds, setSeconds] = useState(0); // 초기값으로 0
    
    useEffect(() => {
    	const interval = setInterval(() => setSeconds(s => s + 1), 1000);
        
        return () => {
            clearInterval(interval) // 컴포넌트 언마운트 시 타이머 정리
        };
    }, []); // 마운트/언마운트 시에만 실행
    
    return <p>Seconds: {seconds}</p>
}

// 마운트/언마운트 : 컴포넌트가 dom에서 렌더링/제거되는 과정

useState, useEffet 비교

특성 useState useEffet
주요 역할 상태(state) 관리 부수 효과(side effect) 처리
사용 위치 함수형 컴포넌트 내부 함수형 컴포넌트 내부
동작 위치 상태값 업데이트 시 렌더링 이후 (의존성 배열에 따라)
리턴값 [state, setState] undefined 또는 정리 함수 (clean-up)
주요 예제 입력값, 토글 상태, 카운터 등 관리 api 호출, 타이머 설정, 구독 관리, dom 조작 등

 

 

종합 예제 : useState로 상태를 관리하고, useEffet로 그 상태에 따른 부수 효과를 처리한다.

import React, { useState, useEffect } from 'react';

function App() {
	const [count, setCount] = useState(0);
    
    useEffect(() => {
    	consol.log('Count가 ${count}로 변경됨');
        
        return () => {
            console.log('정리 작업 : 이전 Count는 ${count}');
        };
    }, [count]); // count가 변경될 때 실헹
    
    return (
    	<div>
            <p>Count: {count}</p>
            <button onClick={() => setCount(count + 1)}>Increase</button>
        </div>
    );
}