나는 오늘도 멋있다

Context API(useContext, createContext) 본문

Web/ReactJS

Context API(useContext, createContext)

나는 오늘도 멋있다 2024. 1. 21. 17:17
1. 모든 행동에는 목표를 정하고 근거가 있어야 한다.
2. 문제가 발생하면 해결이 아닌 원인을 찾아야 한다.
3. 다른사람의 관점을 고려해야한다.

학습목적

상태관리와 함께 자주들었던 Context API를 들었을때는 전역상태관리 할때 쓰이는것 아닌가? 라는 생각만을 가지고 있었다.
보통 "가벼운 프로젝트에서 사용하기좋다", "좀더 큰프로젝트에서는 다른 상태관리 라이브러리" 라는 글들을 보았다.
왜그럴까? 사용법을 알아아보고 그에 대한 이유를 알아보자. 모든내용은 내가 추측한 것이아닌 공식문서의 내용을 토대로 하며,  요약 타이틀에만 나의 의견을 반영한다.


Context API란?

Context API는 React에서 제공하는 기능으로, 컴포넌트 간에 Props를 통해 명시적으로 정보를 전달하지 않고도 하위 트리 구성요소에서 일부정보를 사용할수 있도록 하는 전역 상태 도구이다. 이를 통해 prop drilling을 피하고 상위요소 부터 깊은 하위요소까지의 정보를 쉽게 공유하고 업데이트 할수 있다. 간혹 라이브러리로 착각 하는데, 라이브러리는 외부에서 제공되는 코드 모음을 말하는것으로, Context API의 구성요소들중 useContext, createContext는 React가 제공하는 기능중 하나로 도구 라는 표현이 더올바르다.

출처: React.dev


Context API 구성요소
useContext(Context)
Context를 읽고 구독할수 있게 해주는 React Hook이다.
이중 매개변수인 Context는 createContext를 사용하여 만든 Context를 말한다. Context를 구독하고 있다는 말은 매개변수로 주어진 Context의 값이 변경될때 컴포넌트가 해당 변경사항을 감지하고 다시 렌더링 된다는것을 의미한다.

[매개변수]
Context: CreateContext를 사용하여 만든컨텍스트
 

useContext – React

The library for web and native user interfaces

react.dev


createContext(defaultVale)
Context를 생성하고 제공하여 읽을수 있게 해주는 함수이며 Context객체를 반환한다.(useContext의 매개변수로 사용된다.)

[매개변수]
defaultVale: 하위요소에서 Context를 참고하려할때, Context.Provider가 없는 경우 Context에 포함하려는 정적인 값, 즉 초기값이다.

[컨텍스트의 컴포넌트]
Context.Provider: 공급자 컴포넌트로 래핑하여, 공급자 컴포넌트로 래핑된 하위구성요소에 대해 Context의 값을  value prop을 사용하여 초기 값이아닌 다른 값으로 재정의 할 수있다. 
Context.Consumer: useContext가 나오기 이전에 사용된 공급자 컴포넌트로, Provider와 같은 동작을 하지만 문법에 대한 차이가 있다.
 

createContext – React

The library for web and native user interfaces

react.dev


Context API 구성요소 사용방식

 

  • Context.Provider & Context.Consumer

Context API 주의사항

- 공급자의 범위: useContext로 Context를 호출하는 컴포넌트는,  구성요소의 Context.Provider를 고려 하지 않는다.

- 공급자의 참조: useContext를 통해 전달한 Context는 Context Value를 반환한다. Context Value를 결정할때는 상위로 검색하고 컨텍스트 공급자를 찾아 반환한다.

- 공급자의 렌더링: 특정 컨텍스트를 사용하는 자식 컴포넌트들은, 값이 변경된 프로바이더로부터 시작하여 다시 렌더링한다.

- 공급자의 상태변경: 시간이 지남에 따라 컨텍스트를 변경할경우에는 useState와 함께 사용해야한다.

- 공급자의 재정의: Context.Provider를 중첩하여 컨텍스트의 값을 재정의 할 수 있다.

- 공급자의 Props: Context.Provider의 value Props를 전달하지않으면 undefinde를 전달한다.

- 공급자의 Props명: Context.Provider에 Prop명이 value가 아닌 다른 이름을 사용할수 없다.

- 공급자의 초기값: CreateContext로 생성하는 초기값은 절대 변하지 않는다.(변하면 안된다.)

- 공급자 간의 값재정의: 서로 다른 Context는 서로를 재정의하지 않아야 한다.

- 최상위 레벨 호출: useContext, CreateContext는 구성요소의 최상위 수준에서 호출해야 한다.


Context API에 대한 개인적인 의견

Context API구성요소,사용방식,주의사항에 대해서 알아봤다. ContextAPI 말고 다른 전역 상태관리는 Redux를 단순하게 사용해본 경험있다. 확실히 Redux보다는 구조적으로도 단순하고, 빠르게 적용할수 있는 편이 장점이다.  Redux는 reducer함수를 정의하고, action객체를 정의하고, dispatch함수를 통하여 action을 reducer함수로 보내 store의 상태를 변경하는 방식인 반면에, ContextAPI는 단순히 초기값을 지정하고, 공급자를 통해 각컴포넌트에 값을 재정의하여 보낼수 있고, 해당 Context를 쓰는 하위요소들은 단순히 useContext를 사용하여 값을 읽어올수 있는 단순함이 있다. 그렇다면 ContextAPI를 사용하면 되지않나? 라고 생각할수 있을것 같다. 하지만 전역 상태관리도 많은 상태를 관리하면 유지보수가 힘든것처럼,  ContextAPI의 값을 변경하고 사용하고 전달하기위해서는 useState Hook과 사용해야한다. 그렇다면 특정 컴포넌트에서 결국에는 useState를 생생하게 될것이고, 이로인해 간단하다고 생각했던 ContextAPI 도 복잡성을 가질수가 있다. 사용되는 프로젝트에 따라 상태관리를 어떻게 해야할지 선택해야하는 부분은 이런부분을 말하는 것같다. 전역상태에 대해서 단순히 읽고 값이 다양하게 변환되는것이 아니라면, Context API를 사용해도좋고, 하나의 상태에 대해서 값이 다양하게 변환된다면 Redux를 통해 관리하는것이 유지보수가 더쉬울거라고 생각한다. 그렇기에 작은프로젝트에는 ContextAPI, 큰프로젝트에는 상태관리 라이브러리, 에대한 말이 나오는것같다. 프로젝트의 규모카 클수록 그만큼 복잡해지는 상태에 대해서 분할하는 것 보다는 Redux처럼 하나의 Reducer함수로 관리하는것이 유지보수성에서 좋다고 생각한다.  프로젝트의 규모에 따라 상태관리를 선택한다기 보다는, 프로젝트의 특성을 고려하는 것이 더 좋은것 같다.(물론 Redux는 좋은 미들웨어가 많다.)


Context API 참고문서

[useContext]

 

useContext – React

The library for web and native user interfaces

react.dev

[createContext]

 

createContext – React

The library for web and native user interfaces

react.dev

[context API]

 

Passing Data Deeply with Context – React

The library for web and native user interfaces

react.dev

 

'Web > ReactJS' 카테고리의 다른 글

useReducer Hook  (0) 2024.01.14
React.memo  (0) 2024.01.06
useCallback hook  (0) 2024.01.05
useMemo hook  (0) 2024.01.03
useRef hook  (0) 2023.12.31