궁극의 React Hooks 가이드
Source: Dev.to
소개
React Hooks는 함수 컴포넌트에서 React 상태와 라이프사이클 기능에 “연결”할 수 있게 해주는 함수들입니다. React 16.8에서 도입되었습니다. 아래는 일반적인 React Hook 목록과 설명, 사용 예시입니다. 또한 이 가이드에서는 커스텀 Hook을 만드는 방법도 다룹니다.
1. useState
useState 훅을 사용하면 함수형 컴포넌트에 상태를 추가할 수 있습니다.
설명
useState는 두 개의 요소를 가진 배열을 반환합니다: 현재 상태 값과 이를 업데이트하는 함수.
사용법
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
You clicked {count} times
setCount(count + 1)}>
Click me
);
}
위 코드 블록 내부와 JSX 문자열은 그대로 유지되었습니다.
2. useEffect
useEffect 훅은 함수형 컴포넌트에서 부수 효과(side effect)를 수행할 수 있게 해줍니다.
의존성을 가진 useEffect
useEffect는 최초 렌더링 이후와 모든 업데이트 이후에 실행됩니다. 의존성 배열을 지정하여 효과가 실행되는 시점을 제어할 수 있습니다.
사용법
import React, { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;
}, [count]);
return (
You clicked {count} times
setCount(count + 1)}>
Click me
);
}
빈 의존성 배열 []을 가진 useEffect
초기 렌더링 직후 한 번만 실행됩니다 (componentDidMount와 유사).
useEffect(() => {
console.log('This runs only once after the first render');
}, []);
사용 예: 컴포넌트가 마운트될 때 데이터 가져오기, 이벤트 리스너 설정 등.
의존성이 없는 useEffect
렌더링마다 (초기 렌더링 및 이후 재렌더링) 실행됩니다.
useEffect(() => {
console.log('This runs after every render');
});
사용 예: 특정 상태 변화에 의존하지 않는 코드 실행, 예를 들어 로그 출력이나 애니메이션 등.
useEffect의 정리(Cleanup) 함수
useEffect가 함수를 반환하면, 그 함수는 다음 효과가 실행되기 전이나 컴포넌트가 언마운트될 때 실행되는 정리 작업으로 동작합니다.
useEffect(() => {
const interval = setInterval(() => {
console.log('Interval running...');
}, 1000);
return () => {
clearInterval(interval); // Cleanup on unmount
};
}, []);
사용 예: 이벤트 리스너 정리, API 호출 취소, 인터벌 해제 등.
3. useContext
useContext 훅은 컨텍스트의 값을 접근할 수 있게 해줍니다.
설명
useContext는 컨텍스트 객체( React.createContext 로부터 반환된 값)를 받아 현재 컨텍스트 값을 반환합니다.
사용법
import React, { useContext } from 'react';
const MyContext = React.createContext();
function MyComponent() {
const value = useContext(MyContext);
return {value};
}
function App() {
return (
);
}
4. useReducer
useReducer 훅은 복잡한 상태 로직을 관리하기 위해 useState를 대체할 수 있는 방법입니다.
Explanation
useReducer는 현재 상태와 상태 업데이트를 트리거하는 dispatch 함수를 포함한 배열을 반환합니다.
Usage
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('Unknown action');
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
Count: {state.count}
dispatch({ type: 'increment' })}>
Increment
dispatch({ type: 'decrement' })}>
Decrement
);
}
5. useCallback
useCallback 훅은 메모이제이션된 콜백을 반환합니다.
설명
useCallback은 의존성 중 하나가 변경될 때만 바뀌는 메모이제이션된 콜백 버전을 반환합니다.
사용법
import React, { useState, useCallback } from 'react';
function Counter() {
const [count, setCount] = useState(0);
const increment = useCallback(() => {
setCount(prevCount => prevCount + 1);
}, [count]);
return (
You clicked {count} times
Click me
);
}
6. useMemo
useMemo 훅은 메모이제이션된 값을 반환합니다.
Explanation
useMemo는 의존성 중 하나가 변경될 때만 메모이제이션된 값을 다시 계산합니다.
Usage
import React, { useState, useMemo } from 'react';
function ExpensiveComponent({ value }) {
// Simulate an expensive calculation
const computed = useMemo(() => {
let result = 0;
for (let i = 0; i Result: {computed};
}
useRef, useLayoutEffect와 같은 추가 훅이나 프로젝트 요구에 맞춘 커스텀 훅을 사용해 이 가이드를 자유롭게 확장하세요.
6. useMemo (추가 예제)
function ExpensiveCalculationComponent() {
const [count, setCount] = useState(0);
const [value, setValue] = useState("");
const expensiveCalculation = useMemo(() => {
// Assume this is an expensive calculation
return count * 2;
}, [count]);
return (
Expensive Calculation: {expensiveCalculation}
setCount(count + 1)}>Increment
setValue(e.target.value)} />
);
}
7. useRef
useRef 훅은 변경 가능한 ref 객체를 반환합니다.
Explanation
useRef는 DOM 요소에 접근하거나 렌더링 사이에 값을 유지하는 데 유용합니다.
Usage
import React, { useRef } from "react";
function TextInputWithFocusButton() {
const inputEl = useRef(null);
const onButtonClick = () => {
inputEl.current.focus();
};
return (
Focus the input
);
}
8. useImperativeHandle
useImperativeHandle 훅은 ref를 사용할 때 노출되는 인스턴스 값을 사용자 정의합니다.
설명
useImperativeHandle은 React.forwardRef와 함께 사용해야 합니다.
사용법
import React, { useRef, useImperativeHandle, forwardRef } from "react";
const FancyInput = forwardRef((props, ref) => {
const inputRef = useRef();
useImperativeHandle(ref, () => ({
focus: () => {
inputRef.current.focus();
},
}));
return ;
});
function Parent() {
const inputRef = useRef();
return (
inputRef.current.focus()}>Focus Input
);
}
9. useLayoutEffect
useLayoutEffect 훅은 모든 DOM 변형이 일어난 후에 실행됩니다.
설명
useLayoutEffect는 useEffect와 유사하지만, 모든 DOM 변형이 일어난 직후에 동기적으로 실행됩니다.
사용법
import React, { useLayoutEffect, useRef } from "react";
function LayoutEffectComponent() {
const divRef = useRef();
useLayoutEffect(() => {
console.log(divRef.current.getBoundingClientRect());
});
return Hello, world!;
}
10. useDebugValue
useDebugValue 훅은 React DevTools에서 사용자 정의 훅에 라벨을 표시하는 데 사용됩니다.
설명
useDebugValue는 사용자 정의 훅을 디버깅할 때 도움이 될 수 있습니다.
사용법
import React, { useState, useDebugValue } from "react";
function useFriendStatus(friendID) {
const [isOnline, setIsOnline] = useState(null);
useDebugValue(isOnline ? "Online" : "Offline");
// Imagine this is an actual implementation
return isOnline;
}
11. 커스텀 훅
커스텀 훅은 컴포넌트 로직을 재사용 가능한 함수로 추출할 수 있게 해줍니다.
설명
커스텀 훅은 다른 훅을 호출할 수 있는 일반 JavaScript 함수입니다.
예시: useFetch
import { useState, useEffect } from "react";
function useFetch(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch(url)
.then((response) => response.json())
.then((data) => {
setData(data);
setLoading(false);
});
}, [url]);
return { data, loading };
}
export default useFetch;
커스텀 훅 사용 예시
import React from "react";
import useFetch from "./useFetch";
function App() {
const { data, loading } = useFetch("https://api.example.com/data");
if (loading) {
return Loading...;
}
return (
{JSON.stringify(data, null, 2)}
);
}
export default App;
이 가이드는 React 훅에 대한 포괄적인 개요와 사용 방법, 그리고 커스텀 훅을 만드는 방법을 제공합니다.