일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 성능최적화
- 리뷰
- webGPU
- frontend
- 자바스크립트
- 백준
- React Query
- FE
- javascript
- 성장일지
- naver
- React
- 개발공부
- 테스트 코드
- 항해 플러스 프론트엔드
- GPU
- 항해
- 회고
- 개발자
- 프론트엔드
- 항해 플러스
- 개발 공부
- typescript
- rust
- wil
- 항해99
- 알고리즘
- 항해플러스
- 분기 회고
- 보안
- Today
- Total
느릿늘있
[React Hooks] useContext 이해하기 본문
React에서는 다양한 Hooks를 사용해서 컴포넌트의 상태를 관리하는 패러다임을 제시합니다. 그 중 하나로 useContext라는 훅이 있는데요. 실무에서 자주 써본 것이 아니라면 그냥 전역 상태 관리를 할 수 있게 해주는 훅이다 정도로 알고 있을 겁니다. 저 또한 그랬기에 이번 기회에 useContext에 대해 공식 문서를 보면서 꼼꼼하게 정리해보려고 합니다!
https://ko.react.dev/reference/react/useContext
React의 공식 문서에는 useContext를 컴포넌트에서 Context를 읽고 구독할 수 있는 React Hook이라고 설명하고 있습니다. 이 말을 이해하려면 우선 Context(문맥, 맥락)가 뭔지를 알아야 하는데요. React에서 Context는 그냥 말하자면 전역 상태를 의미합니다. 하지만 Context라는 단어를 놓고 생각하자면 글(코드, 컴포넌트)을 둘러싼(감싸고 있는) 문맥(전역 상태)이다라고 이해할 수 있을 것 같습니다. 즉 이 프로그램이 전체적으로 어떤 맥락에서 실행되고 있는가를 설정하고 보여주는 역할을 하는 것이 바로 컨텍스트입니다. 실제로 내부 컴포넌트에서 그 맥락 속에서 필요한 정보(상태)들을 쏙쏙 뽑아서 사용하고 있는 것이지요.
React에서 Context는 생성(Create) - 제공(Provide) - 사용(Consume)이 라는 아주 명료한 과정으로 구성됩니다. 그리고 이 과정을 선언적으로 사용할 수 있게 도와주는 도구가 바로 Context API인 것이죠.
1. 생성 (Create)
Context를 생성하는 Context API는 createContext(defaultValue)입니다. createContext는 context 객체를 반환하는데요. 공식 문서에도 나와 있듯이 context 객체는 별로 대단한 게 없는 그냥 createContext할 때 인자로 전달한 defaultValue 객체입니다. 다만 여기에 Provider, Consumer, DisplayName을 기본 속성으로 갖고 있다는 점이 유일한 특징입니다.
const contextObject = createcreateContext({
myData1: "기본값1",
myData2: "기본값2"
})
// 여기서 contextObject는 단지 Provider, Consumer, Display를 갖게 될 뿐이고 이를 단순하게 표현하면 아래와 같다.
contextObject = {
Provider,
Consumer,
DisplayName: "Context",
myData1: "기본값1",
myData2: "기본값2"
}
2. 제공 (Provide)
위에서 생성한 Context를 제공하는 방법은 단순하게 해당 Context를 주입할 컴포넌트들을 모두 감싸고 value로 값을 전달하면 됩니다.
import { ContextObject } from '00000.js'
export default function ComponentA() {
...
const myData1 = "문맥값1";
const myData2 = "문맥값2";
// 생성한 Context의 Provider로 감싸고 value로 전역 상태값을 주입한다.
return (<ContextObject.Provider value={
myData1: myData1,
myData2: myData2,
}>
<Page />
</ContextObject.Provider>)
}
3. 사용 (Consume)
이 글의 제목인 useContext가 바로 이 사용 단계에서 쓰이는 훅입니다. useContext 훅이 생기기 전 사용 단계의 코드는 어떻게 생겼었는 지부터 알아보시죠.
// Page.jsx
import { ContextObject } from '00000.js'
export default function ComponentA() {
...
return (<ContextObject.Consumer>
{({ myData2 }) => (<div>{myData2}</div>)}
</ContextObject.Consumer>)
}
위 코드처럼 Provider 내부의 컴포넌트에서 또 한번 Consumer로 내부 요소들을 감싸서 그 안에서 Provider에서 주입한 데이터를 불러와서 사용하고 있습니다. 어려운 내용은 아니지만 설명하는 말부터도 복잡하게 느껴집니다. 이런 방식은 상당히 React스럽지 못하다라고 할 수 있습니다. 보다 React스러운 오늘의 주제, useContext가 어떻게 Context를 사용(Consume)하는 지 알아보시죠.
// Page.jsx
import { ContextObject } from '00000.js'
import { useContext } from 'react';
export default function ComponentA() {
...
const { myData2 } = useContext(ContextObject);
return <div>{myData2}</div>;
}
JSX 내부에 거추장스럽게 존재하던 Consumer 요소가 사라지고 컴포넌트 함수 내에서 이를 사용할 수 있게 되었습니다. 예시만 보면 생각보다 줄어드는 코드의 양이 많지 않다고 느낄 수도 있을 것 같은데요. 그것과는 별개로 상당히 React스러운 코드가 되었다는 사실에는 이견이 없을 것 같습니다.
Context 객체의 3가지 기본 속성 중 DisplayName은 Context의 동작과는 크게 상관이 없습니다. 다만 React DevTools에서 해당 컨텍스트를 디버깅할 때 표출할 이름을 정해준다라고만 아시면 될 것 같습니다.
useContext를 사용할 때는 아래 3가지 주의사항을 꼭 기억해주세요!
- 컨텍스트 값이 변경되면 해당 컨텍스트를 사용하는 모든 컴포넌트가 리렌더링됩니다.
- 성능 최적화를 위해 필요한 경우 컨텍스트를 분리하거나 메모이제이션을 사용할 수 있습니다.
- 컨텍스트는 자주 변경되는 값보다는 테마, 인증 정보 등 비교적 안정적인 값에 적합합니다.
끝으로 Context API를 프로젝트에 도입할 지 고민 중이시거나 더 잘 써보고 싶으시다면 아래 블로그 글을 추천드립니다!
https://velog.io/@velopert/react-context-tutorial
'개발공부' 카테고리의 다른 글
[TypeScript] 포스텔의 법칙 In TypeScript (w. 이펙티브 타입스크립트) (0) | 2024.12.17 |
---|---|
참조값의 깊이에 대한 고찰 (feat. 복사와 비교) (3) | 2024.10.12 |
브라우저 웹 스토리지와 인증 (0) | 2024.09.18 |
우당탕탕 RUST 도전기 (2) (0) | 2024.09.18 |
우당탕탕 RUST 도전기 (1) (0) | 2024.06.23 |