본문 바로가기

기술스택/React.js

[React 19] useContext

앞선 포스팅에 이어, useContext도 같은 맥락으로 오래전부터 존재하던 hook이다.

 

React에서의 데이터 흐름을 생각해보면 일반적으로 부모 컴포넌트에서 자식 컴포넌트로 props를 통해 넘겨주게 된다.

부모 -> 자식으로만 이동하므로 '단방향'이라고 할 수 있다.

 

그러나 전역(global)으로 사용되는 데이터를 컴포넌트 트리에서 단방향으로 계속 넘겨주는 구조는 효율적이라고 말하기 어렵다.

 

React에서는 이러한 문제점을 해결할 수단으로 Context API를 제공한다.

 

부모 컴포넌트의 데이터를 자식 컴포넌트가 참조할 때 자식 컴포넌트가 부모 컴포넌트의 부모 컴포넌트에 있는 값을 받아오려면 순차적으로 부모의 부모 -> 부모 -> 자식 순서로 받아와야 하지만, Context API를 사용하면 다이렉트로 값을 참조하여 사용할 수 있다.

 

여기서 한가지 의문, 그러면 context를 주로 사용하면 되는데 왜 props라는 개념을 사용해야 할까?

 

React의 레거시 문서에 관련 내용이 있다.

 

context의 주된 용도는 다양한 레벨에 네스팅된 많은 컴포넌트에게 데이터를 전달하는 것입니다. context를 사용하면 컴포넌트를 재사용하기가 어려워지므로 꼭 필요할 때만 쓰세요.

여러 레벨에 걸쳐 props 넘기는 걸 대체하는 데에 context보다 컴포넌트 합성이 더 간단한 해결책일 수도 있습니다.

 

Context를 사용하는 적절한(?) 예시를 살펴보면

 

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

// 인증 상태를 관리할 Context 생성
const AuthContext = createContext();

export function useAuth() {
  return useContext(AuthContext);
}

export function AuthProvider({ children }) {
  const [user, setUser] = useState(null);

  const login = (userData) => {
    setUser(userData);
  };

  const logout = () => {
    setUser(null);
  };

  return (
    <AuthContext.Provider value={{ user, login, logout }}>
      {children}
    </AuthContext.Provider>
  );
}

 

이렇게 Provider 역할을 하는 컴포넌트를 생성하고, App 전체를 Provider로 감싸버리면

 

import React from 'react';
import { AuthProvider } from './AuthContext';
import Header from './Header';
import Dashboard from './Dashboard';

function App() {
  return (
    <AuthProvider>
      <Header />
      <Dashboard />
    </AuthProvider>
  );
}

export default App;

 

직접적인 부모 자식 관계에 있는 컴포넌트가 아니라고 할지라도 값을 참조하여 사용할 수 있다.

 

import React from 'react';
import { useAuth } from './AuthContext';

function Header() {
  const { user, login, logout } = useAuth();

  return (
    <header>
      {user ? (
        <>
          <p>Welcome, {user.name}!</p>
          <button onClick={logout}>Logout</button>
        </>
      ) : (
        <button onClick={() => login({ name: 'John Doe' })}>Login</button>
      )}
    </header>
  );
}

export default Header;

 

다만, 부모자식관계에서만 데이터를 교환하는 형태인 경우에는 context를 쓰는 것은 오히려 비효율적이며 오남용시 렌더링 성능이 저하될 수 있다.

 

다시 말해서 Context API는 다수의 컴포넌트에 동일한 데이터를 전달할 때 사용을 고려해야 한다.

이보다도 다수의 컴포넌트를 합성하는 것이 오히려 더 나은 해결책이 될 수도 있다.

 

 

'기술스택 > React.js' 카테고리의 다른 글

[React 19] useMemo  (0) 2025.03.30
[React 19] useEffect  (1) 2025.03.26
[React 19] useCallback  (0) 2025.03.23
[React 19] useActionState  (1) 2025.03.22
[React.js] 이미지 / 파일 업로더 구현  (0) 2022.05.05