프론트엔드 심화 – React Hooks와 Context API

React는 현대 웹 애플리케이션 개발에서 필수적인 프레임워크로 자리 잡았습니다. 이 포스팅에서는 React의 심화 주제인 React Hooks와 Context API를 다룹니다.


React Hooks


React Hooks는 함수형 컴포넌트에서도 상태와 라이프사이클 기능을 사용할 수 있게 해주는 기능입니다. 2018년 React 16.8 버전에서 도입된 Hooks는 클래스형 컴포넌트에서만 사용할 수 있었던 기능을 함수형 컴포넌트에서도 사용할 수 있게 합니다.


기본 Hooks


useState


useState는 상태 변수를 함수형 컴포넌트에서 사용할 수 있게 해주는 Hook입니다.


import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increase</button>
    </div>
  );
}

export default Counter;

useEffect


useEffect는 사이드 이펙트를 처리하기 위한 Hook입니다. 데이터 fetching, 구독(subscription) 설정, 수동으로 DOM을 변경하는 작업 등에 사용됩니다.


import React, { useState, useEffect } from 'react';

function Example() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    document.title = `You clicked ${count} times`;
  }, [count]); // count가 변경될 때마다 실행

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>Click me</button>
    </div>
  );
}

export default Example;

고급 Hooks


useContext


useContext는 Context API를 사용하여 컴포넌트 트리 전체에서 데이터를 쉽게 전달할 수 있게 해주는 Hook입니다.


import React, { useContext } from 'react';

const MyContext = React.createContext();

function Display() {
  const value = useContext(MyContext);
  return <div>{value}</div>;
}

function App() {
  return (
    <MyContext.Provider value="Hello, World!">
      <Display />
    </MyContext.Provider>
  );
}

export default App;

useReducer


useReducer는 복잡한 상태 로직을 다룰 때 유용한 Hook입니다. Redux와 유사한 패턴으로 상태 관리를 할 수 있습니다.


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' })}>Increase</button>
      <button onClick={() => dispatch({ type: 'decrement' })}>Decrease</button>
    </div>
  );
}

export default Counter;

Context API


Context API는 컴포넌트 트리 전체에 데이터를 전역으로 전달할 수 있게 해주는 React의 기능입니다. 주로 전역 상태 관리, 테마 설정, 사용자 인증 정보 전달 등에 사용됩니다.


Context 생성


Context는 React.createContext 함수를 사용하여 생성합니다.


const MyContext = React.createContext(defaultValue);

Provider


Provider 컴포넌트를 사용하여 Context의 값을 설정하고 하위 컴포넌트에 전달합니다.


import React from 'react';

const MyContext = React.createContext();

function App() {
  return (
    <MyContext.Provider value="Hello, World!">
      <Display />
    </MyContext.Provider>
  );
}

function Display() {
  return (
    <MyContext.Consumer>
      {value => <div>{value}</div>}
    </MyContext.Consumer>
  );
}

export default App;

Consumer


Consumer 컴포넌트를 사용하여 Context의 값을 하위 컴포넌트에서 사용할 수 있습니다.


function Display() {
  return (
    <MyContext.Consumer>
      {value => <div>{value}</div>}
    </MyContext.Consumer>
  );
}

useContext Hook


앞서 소개한 useContext Hook을 사용하여 Context의 값을 더 간편하게 사용할 수 있습니다.


import React, { useContext } from 'react';

const MyContext = React.createContext();

function Display() {
  const value = useContext(MyContext);
  return <div>{value}</div>;
}

function App() {
  return (
    <MyContext.Provider value="Hello, World!">
      <Display />
    </MyContext.Provider>
  );
}

export default App;

React Hooks와 Context API 예제 프로젝트


이제 React Hooks와 Context API를 사용하여 간단한 테마 설정 애플리케이션을 만들어보겠습니다. 사용자는 버튼을 클릭하여 테마를 변경할 수 있습니다.


프로젝트 설정


먼저 프로젝트 디렉토리를 설정하고 필요한 패키지를 설치합니다.


npx create-react-app theme-toggle
cd theme-toggle
npm install

테마 설정을 위한 Context 생성


src 폴더에 ThemeContext.js 파일을 만들고 다음 코드를 작성합니다.


import React, { useState, createContext } from 'react';

const ThemeContext = createContext();

const ThemeProvider = ({ children }) => {
  const [theme, setTheme] = useState('light');

  const toggleTheme = () => {
    setTheme(prevTheme => (prevTheme === 'light' ? 'dark' : 'light'));
  };

  return (
    <ThemeContext.Provider value={{ theme, toggleTheme }}>
      {children}
    </ThemeContext.Provider>
  );
};

export { ThemeContext, ThemeProvider };

App 컴포넌트 수정


src/App.js 파일을 열고 다음과 같이 수정합니다.


import React from 'react';
import { ThemeProvider } from './ThemeContext';
import ThemedComponent from './ThemedComponent';

function App() {
  return (
    <ThemeProvider>
      <ThemedComponent />
    </ThemeProvider>
  );
}

export default App;

ThemedComponent 컴포넌트 만들기


src 폴더에 ThemedComponent.js 파일을 만들고 다음 코드를 작성합니다.


import React, { useContext } from 'react';
import { ThemeContext } from './ThemeContext';

function ThemedComponent() {
  const { theme, toggleTheme } = useContext(ThemeContext);

  return (
    <div style={{
      background: theme === 'light' ? '#fff' : '#333',
      color: theme === 'light' ? '#000' : '#fff',
      padding: '20px',
      textAlign: 'center'
    }}>
      <h1>{theme === 'light' ? 'Light Theme' : 'Dark Theme'}</h1>
      <button onClick={toggleTheme}>Toggle Theme</button>
    </div>
  );
}

export default ThemedComponent;

결과 확인


애플리케이션을 실행하여 테마 변경 기능이 정상적으로 작동하는지 확인합니다.


npm start

브라우저에서 http://localhost:3000을 열어 테마 변경 버튼을 클릭하면 배경색과 텍스트 색상이 변경되는 것을 확인할 수 있습니다.


결론


React Hooks와 Context API는 React 개발에서 강력한 도구입니다. Hooks를 사용하면 함수형 컴포넌트에서도 상태와 사이드 이펙트를 관리할 수 있으며, Context API를 사용하면 전역 상태를 쉽게 관리할 수 있습니다. 이 포스팅에서는 기본 Hooks와 고급 Hooks, 그리고 Context API의 사용법을 예제와 함께 설명하였습니다. 앞으로 더 복잡한 애플리케이션을 개발할 때 이러한 기능을 활용하여 코드를 더욱 효율적이고 관리하기 쉽게 만들 수 있습니다.

이 포스팅이 React Hooks와 Context API를 이해하는 데 도움이 되길 바랍니다. 질문이나 추가 정보가 필요하시면 언제든지 댓글로 남겨주세요.

다음 이전