본문 바로가기
프론트엔드/React

React context / useContext()

by 학습하는 청년 2024. 4. 18.

최종 수정 : 2024-04-21

Context


prop drilling이 발생하는 이유 - 단방향 전달

리액트 애플리케이션에서는 데이터가 컴포넌트의 props를 통해 부모에서 자식으로 단방향 전달만 가능하다. 이런 전달 방식으로 인해 프롭 드릴링(Props Drilling)이 발생한다. 이런 문제를 해결하고자 등장한 것이 바로 Context이다.

context를 이용하면 단계마다 props를 넘겨주지 않고도 컴포넌트 트리 전체에 데이터를 제공할 수 있다. React 컴포넌트 트리 안에서 전역적(global)이라고 볼 수 있는 데이터를 부분적으로 전역변수 처리하여 이용하는 방법이다. 또한 코드 역시 간결해지므로 디버깅 하기에도 굉장히 유리하다. 주로 context를 사용해 활용하는 기능은 다음과 같다.

  • 테마 데이터(dark or light mode)
  • 사용자 데이터 - 로그인 여부, 로그인 정보
  • 로케일 데이터(language or locate)

하지만 무조건 사용하는 것이 능사는 아니다. 컴포넌트가 의존성을 갖게 되므로 재사용성이 떨어진다는 문제가 발생하기 때문이다. 따라서, 컴포넌트를 합성하는 방법도 고려해보는 게 좋다.


적용 방법

context를 쓸 때는 값을 공유할 범위를 정하고 사용해야 한다. 범위는 Provider 라는 컴포넌트로 정해줄 수 있다. 

  1. createContext 메서드를 사용해 context를 생성한다.
  2. 생성된 context를 가지고 context provider로 컴포넌트 트리를 감싼다.
  3. value prop을 사용해 context provider에 원하는 값을 입력한다.
  4. context consumer을 사용해 필요한 컴포넌트에서 그 값을 불러온다.
import React from 'react';
export const UserContext = React.createContext();
export default function App() {
  return (
    <UserContext.Provider value="Reed">
      <User />
    </UserContext.Provider>
  )
}
function User() {
  return (
    <UserContext.Consumer>
      {value => <h1>{value}</h1>} 
      {/* prints: Reed */}
    </UserContext.Consumer>
  )
}

 

useContext() Hooks를 이용하면 다음과 같다.

import React from 'react';
export const UserContext = React.createContext();
export default function App() {
  return (
    <UserContext.Provider value="Reed">
      <User />
    </UserContext.Provider>
  )
}
function User() {
  const value = React.useContext(UserContext);  
    
  return <h1>{value}</h1>;
}

 

중첩하여 사용할 수도 있다.


참고 자료

https://ko.legacy.reactjs.org/docs/context.html

https://www.inflearn.com/course/lecture?courseSlug=%ED%95%9C%EC%9E%85-%EB%A6%AC%EC%95%A1%ED%8A%B8&unitId=103537

https://www.freecodecamp.org/korean/news/cobojareul-wihan-riaegteu-context-wanbyeog-gaideu-2021/

 

Context 중첩 사진 출처

https://velog.io/@velopert/react-context-tutorial

 

 

 

소플의 처음 만난 리액트 (p.380-396 수정중) - 사진 참고

댓글