개발 방법론 & 아키텍쳐

React Hooks 기본 개념 및 사용 방법

atomicdev 2024. 10. 11. 14:22
728x90

React Hooks 기본 개념 및 사용 방법

React Hooks는 React 16.8부터 도입된 기능으로, 클래스형 컴포넌트를 사용할 필요 없이 함수형 컴포넌트에서도 상태(state)와 생명주기(lifecycle) 기능을 사용할 수 있도록 도와줍니다. Hooks는 기존 클래스형 컴포넌트의 복잡성을 줄이고, 재사용 가능한 로직을 간결하게 만들기 위한 중요한 도구입니다.

React 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());
    • 상태 업데이트는 비동기적으로 처리되므로, 상태 값을 설정한 직후에 접근하면 여전히 이전 상태 값일 수 있습니다.

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 사용할 때 주의해야 할 점

  1. Hook은 루프, 조건문, 중첩 함수에서 호출하지 말 것: Hook은 항상 컴포넌트의 최상위 레벨에서 호출해야 합니다. 그렇지 않으면 React의 상태 관리 메커니즘이 예상치 못한 동작을 할 수 있습니다.
  2. 의존성 배열에 신경쓰기: useEffect나 useCallback 같은 Hook에서 의존성 배열을 적절히 설정하지 않으면, 최신 데이터를 참조하지 않거나 불필요한 재렌더링이 발생할 수 있습니다.
  3. 컴포넌트 상태 관리 주의: 상태를 너무 많이 사용하면 성능 저하가 발생할 수 있으므로, 가능한 최소한의 상태만 관리하고 필요할 때 useReducer를 도입해 관리 구조를 간소화해야 합니다.

결론

React Hooks는 React 함수형 컴포넌트의 강력한 도구로, 복잡한 상태 관리나 생명주기 로직을 쉽게 구현할 수 있도록 돕습니다. 기본적인 Hooks를 잘 활용하면 더 깨끗하고 재사용 가능한 컴포넌트를 만들 수 있습니다. 다만 사용 시 주의할 점을 염두에 두어 예상치 못한 문제를 방지하는 것이 중요합니다.

728x90