React Hooks 기본 개념 및 사용 방법
React Hooks는 React 16.8부터 도입된 기능으로, 클래스형 컴포넌트를 사용할 필요 없이 함수형 컴포넌트에서도 상태(state)와 생명주기(lifecycle) 기능을 사용할 수 있도록 도와줍니다. Hooks는 기존 클래스형 컴포넌트의 복잡성을 줄이고, 재사용 가능한 로직을 간결하게 만들기 위한 중요한 도구입니다.
React Hooks의 주요 개념
1. useState
useState는 함수형 컴포넌트에서 상태 값을 관리할 수 있는 Hook입니다. 상태를 저장하고, 이를 변경하는 함수를 반환합니다.
- 구문:
const [state, setState] = useState(initialValue);
- 사용 예제:
import React, { useState } from 'react'; function Counter() { const [count, setCount] = useState(0); return ( <div> <p>Count: {count}</p> <button onClick={() => setCount(count + 1)}>Increment</button> </div> ); } export default Counter;
- 주의사항:
- useState는 초기 값으로 함수 호출을 지원하므로 무거운 계산을 할 경우, 초기 값을 함수로 감싸면 성능이 개선됩니다.
const [count, setCount] = useState(() => calculateInitialValue());
- 상태 업데이트는 비동기적으로 처리되므로, 상태 값을 설정한 직후에 접근하면 여전히 이전 상태 값일 수 있습니다.
- useState는 초기 값으로 함수 호출을 지원하므로 무거운 계산을 할 경우, 초기 값을 함수로 감싸면 성능이 개선됩니다.
2. useEffect
useEffect는 함수형 컴포넌트가 렌더링될 때나 업데이트될 때 특정 작업(사이드 이펙트)을 실행할 수 있는 Hook입니다. 데이터 fetching, DOM 조작, 구독(subscription) 같은 부수 효과를 처리하는 데 자주 사용됩니다.
- 구문:
useEffect(() => { // 실행할 코드 }, [dependencyArray]);
- 사용 예제:
import React, { useState, useEffect } from 'react'; function DataFetcher() { const [data, setData] = useState(null); useEffect(() => { fetch('https://jsonplaceholder.typicode.com/posts/1') .then(response => response.json()) .then(data => setData(data)); }, []); // 빈 배열로 설정 시 컴포넌트가 처음 마운트될 때만 실행 return ( <div> <h1>Fetched Data</h1> <pre>{JSON.stringify(data, null, 2)}</pre> </div> ); } export default DataFetcher;
- 주의사항:
- useEffect에서 사용하는 변수는 의존성 배열에 포함시켜야 합니다. 이를 생략하면 최신 값이 반영되지 않거나 예기치 않은 동작을 일으킬 수 있습니다.
- 클린업 함수를 사용하여 컴포넌트가 언마운트될 때 리소스를 정리할 수 있습니다.
useEffect(() => { const subscription = subscribeToSomeEvent(); return () => { subscription.unsubscribe(); }; }, []);
3. useContext
useContext는 React에서 전역 상태를 쉽게 관리할 수 있는 Hook입니다. 상위 컴포넌트에서 제공된 Context 값을 하위 컴포넌트에서 손쉽게 사용할 수 있습니다.
- 구문:
const value = useContext(MyContext);
- 사용 예제:
import React, { createContext, useContext, useState } from 'react'; const ThemeContext = createContext(); function App() { const [theme, setTheme] = useState('light'); return ( <ThemeContext.Provider value={theme}> <button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}> Toggle Theme </button> <Toolbar /> </ThemeContext.Provider> ); } function Toolbar() { const theme = useContext(ThemeContext); return <div>Current Theme: {theme}</div>; } export default App;
- 주의사항:
- Context는 컴포넌트 트리 전체에 걸쳐 많은 데이터를 공유할 때 사용하지만, 과도한 사용은 컴포넌트를 복잡하게 만들 수 있으므로 필요한 경우에만 사용하는 것이 좋습니다.
4. useReducer
useReducer는 상태 관리 로직이 복잡해지는 경우에 useState 대신 사용할 수 있는 Hook입니다. Redux처럼 상태를 업데이트하는 Reducer 함수 패턴을 사용합니다.
- 구문:
const [state, dispatch] = useReducer(reducer, initialState);
- 사용 예제:
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' })}>Increment</button> <button onClick={() => dispatch({ type: 'decrement' })}>Decrement</button> </div> ); } export default Counter;
- 주의사항:
- 상태가 복잡할 때는 useState보다 useReducer가 더 적합할 수 있습니다. 하지만 지나치게 많은 상태를 useReducer로 관리하는 것은 오히려 복잡해질 수 있습니다.
React Hooks 사용할 때 주의해야 할 점
- Hook은 루프, 조건문, 중첩 함수에서 호출하지 말 것: Hook은 항상 컴포넌트의 최상위 레벨에서 호출해야 합니다. 그렇지 않으면 React의 상태 관리 메커니즘이 예상치 못한 동작을 할 수 있습니다.
- 의존성 배열에 신경쓰기: useEffect나 useCallback 같은 Hook에서 의존성 배열을 적절히 설정하지 않으면, 최신 데이터를 참조하지 않거나 불필요한 재렌더링이 발생할 수 있습니다.
- 컴포넌트 상태 관리 주의: 상태를 너무 많이 사용하면 성능 저하가 발생할 수 있으므로, 가능한 최소한의 상태만 관리하고 필요할 때 useReducer를 도입해 관리 구조를 간소화해야 합니다.
결론
React Hooks는 React 함수형 컴포넌트의 강력한 도구로, 복잡한 상태 관리나 생명주기 로직을 쉽게 구현할 수 있도록 돕습니다. 기본적인 Hooks를 잘 활용하면 더 깨끗하고 재사용 가능한 컴포넌트를 만들 수 있습니다. 다만 사용 시 주의할 점을 염두에 두어 예상치 못한 문제를 방지하는 것이 중요합니다.
'개발 방법론 & 아키텍쳐' 카테고리의 다른 글
Redux 단점 보완: 복잡한 초기설정 (0) | 2024.10.15 |
---|---|
React와 보일러플레이트 개념 (2) | 2024.10.14 |
React 프로젝트에서 다국어 지원: FormatJS, react-i18next, react-intl, Lingui 비교 분석 (0) | 2024.10.10 |
React 프로젝트 상태 관리: Redux, Zustand, Jotai, Recoil 비교 (0) | 2024.10.07 |
React 프로젝트에서 Storybook 사용하는 방법 (0) | 2024.10.07 |