앞선 포스팅에 이어, 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 |