useContext 와 사용 시 주의사항
리액트에서 부모 컴포넌트에서 하위 컴포넌트(자식 컴포넌트)로 데이터를 전달할 때는 props 라는 속성을 인자로 넘겨주어 해당 자식 컴포넌트 내에서 매개변수로 받아와 사용하게 된다. 이러한 방식은 데이터를 명시적으로 연결하는 데 있어서 아주 좋은 방법이지만, 부모 컴포넌트에서 리프 컴포넌트에 도달하는 파이프라인이 길고 복잡할 수록 props 를 사용한 전달 방식은 한계에 봉착할 수 있다.
useContext 는 이러한 문제를 해결할 수 있도록 데이터를 전역적으로 관리할 수 있도록 해준다.
단, 주의할 점은 useContext 는 프로바이더(제공자)를 통해 전달된 값이 존재하는 컴포넌트를 값이 변동될 때 마다 리렌더링한다는 점이다. 따라서 무턱대고 useContext를 사용해서 전역 상태를 관리하는 것은 엄청난 리소스 낭비를 불러일으킬 수 있다. 이 점을 고려한다면, useContext를 사용하는 사례는 다크모드와 같이 자주 쓰이지는 않지만, 전체 컴포넌트에 영향을 미칠 필요가 있는 상태에 대한 처리를 담당하게 하는 것이 여러모로 좋을지도 모른다.
사용방법
[1] context 로 사용할 파일을 하나 만들어서 아래와 같이 createContext를 react 패키지로 부터 가져온 후 정의한다.
// context.js
import {createContext} from 'react'
export const contextExam = createContext(null);
createContext 는 하나의 인자를 할당받을 수 있는데, 이는 초깃값을 의미한다. 이 값을 설정하면, 향후 provider에서 value 값을 지정하지 않는다면 해당 초깃값이 value 을 대체한다.
[2] context 로 연결하고자 하는 컴포넌트로 이동 후 react 패키지의 useContext 와 앞서 생성한 context 파일을 import 해온다.
// page.js
import Header from './components/Header.jsx'
import Content from './components/Content.jsx'
import {ContextExam} from './context/context.js'
export default function Page() {
return (
<main>
<!-- Provider 를 생성하는데, 이 때 value 속성에 지정한 값들이 하위 컴포넌트에서 전역적으로 사용된다 -->
<ContextExam.Provider value ={"context 프로바이더에서 전달됨"}>
<Header></Header>
<Content></Content>
</ContextExam.Provider>
</main>
)
}
이 때 provider 로 감싸진 자식 컴포넌트들은 Provider 의 속성으로 지정된 value 을 props로 전달 받지 않아도 전역적으로 사용할 수 있게 된다.
[3] provider 의 값을 전달 받아 사용하고자 하는 하위(자식) 컴포넌트로 이동하여 다음과 같이 작성한다.
즉, value의 "context 프로바이더에서 전달됨" 이라는 텍스트를 Header.js 컴포넌트에서 사용한다고 가정하면 다음과 같이 Header 컴포넌트에서 useContext( ) 를 import 하고 ( ) 내에 앞선 과정에서 생성한 ContextExam 을 전달하면, 해당 자리에는 provider의 value 값이 남게 된다.
참고) provider 에서 지정된 value은 모든 하위컴포넌트가 전역적으로 전달받아 사용되므로, provider의 value을 변경하면 모든 하위 컴포넌트의 value이 변경된다.
// Header.jsx
import {useContext} from 'react';
import {ContextExam} from '../context/context.js'
const Header=()=>{
// title 이라는 변수에는 Provider의 value 이 할당된다.
const title = useContext(ContextExam)
return (
<header id="header">
<!-- title 에는 context 프로바이더에서 전달됨 이 렌더링된다. -->
<h1>{title}</h1>
</header>
)
}
export default Header
참고해야 하는 공식 문서
https://react.dev/learn/passing-data-deeply-with-context
'리액트' 카테고리의 다른 글
[React] 리액트에서 카카오 맵 불러오기 (with kakao map) (0) | 2023.07.21 |
---|---|
[react] 리액트에서 카카오 맵 사용하기( with ReactKakaoMapSDK) (0) | 2023.07.21 |
[react-router-dom] useSearchParams () 에 대한 정리 (0) | 2023.06.05 |
[react hooks] 2. useMemo() (0) | 2023.05.15 |
[리액트] 키보드 방향키로 페이지 이동하는 기능에 쓰일 코드 저장 (0) | 2023.03.31 |