[React] Context

Byeonghyeon·2025년 1월 17일

공부

목록 보기
10/21

Context

보통의 경우 부모 컴포넌트에서 자식 컴포넌트로 props를 통해 정보를 전달한다.

하지만 부모 -> 중간 1 -> 중간 2 -> 중간 3 -> 목적지처럼 거쳐야 하는 컴포넌트가 많으면 어떨까

이런 경우 props를 전달하는 것이 번거롭고 불편할 수 있다.

Context는 부모 컴포넌트가 트리 아래에 있는 모든 컴포넌트에 깊이에 상관없이 정보를 명시적으로 props를 통해 전달하지 않고도 사용할 수 있게 해준다.

(위 : props 전달, 아래 : Context 사용)

createContext

const SomeContext = createContext(defaultValue)

createContext를 사용하면 컴포넌트가 Context를 제공하거나 읽을 수 있다.

매개변수

  • defaultValue : 컴포넌트가 Context를 읽을 때 상위에 일치하는 Context 제공자가 없는 경우 Context가 가져야 할 값. 의미 있는 기본값이 없으면 null을 지정해야 한다. 기본값은 최후의 수단으로 사용된다. 이 값은 정적이며 시간이 지나도 변경되지 않는다.

반환값

createContext는 컨텍스트 객체를 반환한다.

컨텍스트 객체 자체는 어떠한 정보도 가지고 있지 않다. 다른 컴포넌트가 읽거나 제공하는 어떤 컨텍스트를 나타낸다.

사용법

컨텍스트 생성

컴포넌트 외부에서 createContext를 호출하여 하나 이상의 컨텍스트를 생성한다.

import { createContext } from 'react';

const ThemeContext = createContext('light');
const AuthContext = createContext(null);

createContext는 컨텍스트 객체를 반환한다. 컴포넌트는 이를 useContext()에 전달하여 컨텍스트를 읽을 수 있다.

function Button() {
  const theme = useContext(ThemeContext);
  // ...
}

function Profile() {
  const currentUser = useContext(AuthContext);
  // ...
}

Provider로 컨텍스트를 전달하고 싶은 컴포넌트를 감싸자

function App() {
  const [theme, setTheme] = useState('dark');
  const [currentUser, setCurrentUser] = useState({ name: 'Taylor' });

  // ...

  return (
    <ThemeContext.Provider value={theme}>
      <AuthContext.Provider value={currentUser}>
        <Page />
      </AuthContext.Provider>
    </ThemeContext.Provider>
  );
}

useContext

useContext는 컴포넌트에서 컨텍스트를 읽고 구독할 수 있는 React Hook이다.

const value = useContext(SomeContext)

매개변수

  • SomeContext : createContext로 생성한 Context이다. Context 자체는 정보를 담고 있지 않으며, 컴포넌트에서 제공하거나 읽을 수 있는 정보의 종류를 나타낸다.

반환값

useContext는 호출하는 컴포넌트에 대한 Context 값을 반환한다. 이 값은 트리에서 호출하는 컴포넌트 사우이의 가장 가까운 SomeComponent.Provider에 전달된 값으로 결정된다. Provider가 없으면 반환된 값은 해당 Context에 대해 createContext에 전달한 defaultValue가 된다.

Context가 변경되면 React는 자동으로 해당 Context를 읽는 컴포넌트를 다시 렌더링한다.

사용 예시

모드 체인지 버튼을 눌러 다크모드와 라이트모드를 구현하는 코드를 작성해보았다.

const ThemeContext = createContext(null);

먼저 외부에 ThemeContext를 선언해주자.

/* App.jsx */

function App() {
  const [darkmode, setDarkmode] = useState(false);

  return (
    <ThemeContext.Provider value={{darkmode, setDarkmode}}>
      <Header />
      <Content />
      <Footer />
    </ThemeContext.Provider>
  );
}

export default App;

각각의 컴포넌트들을 ThemContext.Provider로 묶어주었고, value값으로 useState를 통해 선언한 darkmode와 setDarkmode를 전달하였다.

const Header = () => {
  const themeContext = useContext(ThemeContext);

  if (!themeContext) {
    throw new Error("Header must be used within a ThemeContext.Provider");
  }

  const { darkmode } = themeContext;
  return (
    <div
      style={{
        backgroundColor: darkmode ? "black" : "white",
        color: darkmode ? "white" : "black",
      }}
    >
      Header
    </div>
  );
};

코드는 Header이지만, Content나 Footer도 동일하게 작성해주면 된다.

모드 체인지 버튼이 있어야 하므로 Content에 추가해주었다.

<button
      onClick={modeChange}
      style={{
        backgroundColor: darkmode ? "black" : "white",
        color: darkmode ? "white" : "black",
      }}
    >
      mode change
    </button>

modeChange 버튼에 onClick으로 Context로 전달한 setDarkmode를 실행하도록 해주면 된다.

실행해보면 아주 잘 작동하는 것을 볼 수 있다.

0개의 댓글