React Hooks는 함수형 컴포넌트에서 상태 관리와 생명주기 제어를 가능하게 하는 기능이다.
클래스형 컴포넌트의 복잡한 구조를 개선하고, 더 직관적이고 재사용 가능한 코드 작성이 가능하도록 도와준다. 이 글에서는 자주 사용하는 리액트 기본 훅(React Hooks)을 상세한 설명과 예제 코드와 함께 정리하고,
나아가 커스텀 훅(Custom Hook)을 활용하는 방법까지 다뤄보려고 한다. 🛠
React 16.8 버전부터 공식 도입되었다. this.state, this.setState(), componentDidMount() 등 복잡한 클래스형 문법을 없앨 수 있다. 💡 아래 예제에서, 클래스형 컴포넌트와 함수형 컴포넌트 (with Hook)을 비교해 보자.
// 🚫 클래스형 컴포넌트에서 state 사용
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
}
render() {
return (
<div>
<p>Count: {this.state.count}</p>
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
증가
</button>
</div>
);
}
}
// ✅ 함수형 컴포넌트에서 useState 사용
import { useState } from "react";
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>증가</button>
</div>
);
}
✔️ 함수형 컴포넌트 + 훅을 사용하면 코드가 더 간결하고 직관적이다!
useState – 상태 관리👉 useState는 컴포넌트의 상태(state)를 관리하는 훅이다.
✅ 사용법
import { useState } from "react";
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>현재 카운트: {count}</p>
<button onClick={() => setCount(count + 1)}>+1 증가</button>
<button onClick={() => setCount(count - 1)}>-1 감소</button>
</div>
);
}
✅ 특징
useState(initialValue) 초기값을 설정할 수 있다. setState와 다르게, 이전 상태를 기반으로 새로운 값을 설정 가능하다. useEffect – 사이드 이펙트 관리👉 useEffect는 컴포넌트가 마운트/업데이트/언마운트될 때 특정 동작을 수행할 수 있도록 해준다.
✅ 사용법
import { useState, useEffect } from "react";
function Timer() {
const [count, setCount] = useState(0);
useEffect(() => {
console.log(`현재 카운트: ${count}`);
}, [count]); // count 값이 변경될 때마다 실행됨
return (
<div>
<p>카운트: {count}</p>
<button onClick={() => setCount(count + 1)}>증가</button>
</div>
);
}
✅ 특징
useEffect(callback, []) 의존성 배열이 빈 경우, 최초 마운트 시 1회 실행된다. useEffect(callback, [state]) 특정 상태(state)가 변경될 때 실행된다. useRef – DOM 요소 접근👉 useRef는 DOM 요소를 직접 접근하거나, 값이 변경되더라도 리렌더링을 발생시키지 않도록 하는 훅이다.
✅ 사용법
import { useRef, useEffect } from "react";
function InputFocus() {
const inputRef = useRef(null);
useEffect(() => {
inputRef.current.focus(); // 마운트 후 자동으로 포커스
}, []);
return <input ref={inputRef} type="text" placeholder="자동 포커스!" />;
}
✅ 특징
useRef는 렌더링과 관계없이 값을 유지할 수 있다. useMemo – 연산 최적화👉 useMemo는 연산 비용이 큰 계산을 최적화할 때 사용된다.
✅ 사용법
import { useState, useMemo } from "react";
function ExpensiveCalculation({ num }) {
const result = useMemo(() => {
console.log("계산 중...");
return num * 2;
}, [num]);
return <p>결과: {result}</p>;
}
✅ 특징
useMemo는 값을 메모이제이션하여 불필요한 계산을 방지한다. useCallback – 함수 최적화👉 useCallback은 함수를 메모이제이션하여 불필요한 렌더링을 방지하는 훅이다.
✅ 사용법
import { useState, useCallback } from "react";
function Button({ onClick }) {
return <button onClick={onClick}>클릭!</button>;
}
function Parent() {
const [count, setCount] = useState(0);
const handleClick = useCallback(() => {
console.log("버튼 클릭!");
}, []);
return (
<div>
<p>Count: {count}</p>
<Button onClick={handleClick} />
<button onClick={() => setCount(count + 1)}>증가</button>
</div>
);
}
✅ 특징
useCallback은 함수를 메모이제이션하여, 불필요한 재생성을 방지한다. 👉 여러 컴포넌트에서 중복되는 로직을 재사용할 수 있도록 커스텀 훅을 만들 수 있다!
import { useState, useEffect } from "react";
function useWindowWidth() {
const [width, setWidth] = useState(window.innerWidth);
useEffect(() => {
const handleResize = () => setWidth(window.innerWidth);
window.addEventListener("resize", handleResize);
return () => window.removeEventListener("resize", handleResize);
}, []);
return width;
}
function Component() {
const width = useWindowWidth();
return <p>현재 창 너비: {width}px</p>;
}
✔️ React Hooks를 활용하면 함수형 컴포넌트에서도 강력한 기능을 구현할 수 있다.
✔️ useState, useEffect, useMemo, useCallback, useRef 등 핵심 훅을 잘 활용하면 성능을 최적화할 수 있다.