React Hook은 React 16.8 버전에서 도입된 기능으로, 함수형 컴포넌트에서 상태(state)와 생명주기 메서드(lifecycle methods)를 사용할 수 있게 해줍니다. 이로 인해 클래스형 컴포넌트보다 코드가 더 간결하고 이해하기 쉬워졌습니다. 이번 포스트에서는 주요 React Hook인 useState
, useEffect
, useContext
, useReducer
에 대해 설명하고 사용 방법과 주의 사항을 알아보겠습니다.
useState
는 함수형 컴포넌트에서 상태(state)를 관리할 수 있게 해주는 Hook입니다.
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
</div>
);
}
useState
는 반드시 함수형 컴포넌트 또는 Custom Hook 내에서 사용해야 합니다.useState
는 컴포넌트의 최상위 레벨에서만 호출해야 합니다. 반복문, 조건문, 중첩 함수 내에서 호출해서는 안 됩니다.useEffect
는 함수형 컴포넌트에서 사이드 이펙트(side effect)를 처리할 수 있게 해주는 Hook입니다. 예를 들어 데이터 fetching, DOM 조작 등을 처리할 수 있습니다.
import React, { useState, useEffect } from 'react';
function DataFetcher() {
const [data, setData] = useState(null);
useEffect(() => {
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => setData(data));
}, []);
return (
<div>
{data ? <p>{data.name}</p> : <p>Loading...</p>}
</div>
);
}
useEffect
는 컴포넌트의 최상위 레벨에서만 호출해야 합니다.useContext
는 Context API를 사용하여 전역 상태를 쉽게 공유할 수 있게 해주는 Hook입니다. 이를 통해 여러 컴포넌트에서 상태를 쉽게 접근하고 변경할 수 있습니다.
import React, { useContext } from 'react';
import { ThemeContext } from './ThemeContext';
function ThemedComponent() {
const theme = useContext(ThemeContext);
return (
<div style={{ background: theme.background, color: theme.color }}>
Themed Content
</div>
);
}
useContext
는 반드시 함수형 컴포넌트 또는 Custom Hook 내에서 사용해야 합니다.useReducer
는 복잡한 상태 로직을 관리할 때 사용되는 Hook입니다. 상태 로직이 복잡하거나 여러 하위 컴포넌트에서 상태를 관리해야 할 때 유용합니다. useState
의 대안으로 사용할 수 있습니다.
import React, { useReducer } from 'react';
const initialState = { count: 0 };
function reducer(state, action) {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'decrement':
return { count: state.count - 1 };
default:
throw new Error();
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<div>
<p>Count: {state.count}</p>
<button onClick={() => dispatch({ type: 'increment' })}>+</button>
<button onClick={() => dispatch({ type: 'decrement' })}>-</button>
</div>
);
}
useReducer
는 컴포넌트의 최상위 레벨에서만 호출해야 합니다.React Hook을 사용할 때 중요한 조건과 규칙이 몇 가지 있습니다. 이를 잘 지켜야 예상치 못한 오류를 방지하고, 코드의 일관성을 유지할 수 있습니다.
최상위에서만 호출:
Hook은 컴포넌트의 최상위 레벨에서만 호출해야 합니다. 반복문, 조건문, 중첩 함수 내에서 Hook을 호출해서는 안 됩니다. 이 규칙은 매 렌더링마다 Hook이 동일한 순서로 호출되도록 보장합니다.
// 잘못된 예
if (someCondition) {
useEffect(() => {
// ...
}, []);
}
// 올바른 예
useEffect(() => {
if (someCondition) {
// ...
}
}, [someCondition]);
React 함수형 컴포넌트 및 Custom Hook에서만 사용:
Hook은 React 함수형 컴포넌트 또는 직접 정의한 Custom Hook에서만 호출할 수 있습니다. 일반 자바스크립트 함수에서 Hook을 호출해서는 안 됩니다.
// 잘못된 예
function regularFunction() {
const [count, setCount] = useState(0); // Error
}
// 올바른 예
function Component() {
const [count, setCount] = useState(0);
// ...
}
Custom Hook 작성 규칙:
Custom Hook은 이름이 반드시 "use"로 시작해야 합니다. 이는 React가 Hook의 사용을 인식하고, 규칙을 적용할 수 있게 합니다.
// 올바른 Custom Hook 예
function useCustomHook() {
const [state, setState] = useState(initialState);
// ...
return state;
}
React Hook을 사용하면 코드가 더 직관적이고 간결해지며, 클래스형 컴포넌트에서 필요했던 많은 보일러플레이트 코드를 제거할 수 있습니다. 이를 통해 개발자는 React 애플리케이션을 더 쉽게 작성하고 유지관리할 수 있습니다. 각 Hook의 사용 조건과 규칙을 잘 지키면서 코드를 작성하면 예상치 못한 오류를 방지하고, 더욱 효율적인 개발이 가능합니다.
이 글을 통해 React Hook에 대해 이해하고, 실제 프로젝트에서 유용하게 활용하시길 바랍니다.