Context를 사용해 데이터를 깊게 전달하기

박재현·2024년 3월 5일
0

Nomadcoder React Study 4기

목록 보기
24/49

보통의 경우 부모 컴포넌트에서 자식 컴포넌트로 Props를 통해 데이터를 전달한다.
근데 중간에 많은 컴포넌트를 거쳐야 하거나, 응용프로그램에서 많은 컴포넌트에서 동일한 정보들이 필요한 경우에는 props를 전달하는것이 번거롭고 불편할 수 있다.

Context를 사용하면 명시적으로 props를 전달해주지 않아도 부모 컴포넌트가 트리에 있는 어떤 자식 컴포넌트에(부모로부터 얼마나 멀리 떨어져 있던지 간에 상관없음)나 데이터를 사용할 수 있다.


Props 전달하기의 문제점

props를 전달하는것 또한 훌륭한 방법이나 어떠한 prop을 트리를 통해 깊이 전해줘야 하거나, 많은 컴포넌트에서 같은 prop이 필요한 경우에 장황하고 불편할 수 있다.

데이터가 필요한 여러 컴포넌트의 가장 가까운 공통 조상은 트리상 높이 위치할 수 있고, 그렇게 높게까지 state를 끌어 올리는것은 prop drilling이라는 상황을 초래할 수 있다.

동시에 props만으로는 가장 가까운 부모 컴포넌트의 레벨(depth)을 알 수 없다.


props를 사용하면 부모 컴포넌트의 레벨을 알 수 없기에, context가 활약할 수 있게되고, 아래와 같은 3단계로 진행된다.

  1. Context 생성
  2. 데이터가 필요한 컴포넌트에서 context를 사용
  3. 데이터를 지정하는 컴포넌트에서 context를 제공

Context는 부모가 트리 내부 전체에, 심지어 멀리 떨어진 컴포넌트에조차 어떤 데이터를 제공할 수 있도록 한다.


1단계: Context 생성

컴포넌트에서 사용할 수 있도록 파일에서 내보낼 context를 만들어야 한다.

createContext의 유일한 인자는 default value다.

// LevelContext.js

import { createContext } from 'react';

export const LevelContext = createContext(1);

2단계: Context 사용

useContext 훅과 위에서 생성한 Context를 import

import { useContext } from 'react';
import { LevelContext } from './LevelContext.js';

Heading 컴포넌트의 props로 받고있던 level값을 useContext를 사용해 값을 읽도록 수정

// Before
export default function Heading({ level, children }) {
  // ...
}

// After
export default function Heading({ children }) {
  const level = useContext(LevelContext);
  // ...
}

일단 useContext또한 훅이기 때문에 컴포넌트 상단에서 호출할 수 있고, useContext는 React에게 Heading 컴포넌트가 LevelContext를 읽으려 한다고 알려준다.


3단계: Context 제공하기

Section 컴포넌트에서 children을 렌더링하고 있는데,
1단계에서 생성한 LevelContext를 children에게 제공하기 위해서 context provider로 감싸준다.

// Before
export default function Section({ children }) {
  return (
    <section className="section">
      {children}
    </section>
  );
}

// After
import { LevelContext } from './LevelContext.js';

export default function Section({ level, children }) {
  return (
    <section className="section">
      <LevelContext.Provider value={level}>
        {children}
      </LevelContext.Provider>
    </section>
  );
}

context를 사용하면 prop을 각각의 Heading 컴포넌트에 전달할 필요가 없어지고, 대신 위의 가장 가까운 Section 컴포넌트에서 level을 확인한다.

동시에 Level Context를 읽으면서 컴포넌트 스스로 트리 구조에서 얼마나 깊이 있는지 확인할 수 있다. (이건 좀 신기한듯)


요약

  • Context는 컴포넌트가 트리 상 아래에 위치한 모든 곳에 데이터를 제공하도록 합니다.

  • Context를 전달하려면 다음과 같습니다

    	1.export const MyContext = createContext(defaultValue)로 context를 생성하고 내보내세요.
    
    	2. useContext(MyContext) Hook에 전달해 얼마나 깊이 있든 자식 컴포넌트가 읽을 수 있도록 합니다.
    
    	3. 자식을 <MyContext.Provider value={...}>로 감싸 부모로부터 context를 받도록 합니다.
  • Context는 중간의 어떤 컴포넌트도 지나갈 수 있습니다.

  • Context를 활용해 “주변에 적응하는” 컴포넌트를 작성할 수 있습니다.

  • Context를 사용하기 전에 props를 전달하거나 JSX를 children으로 전달하는 것을 먼저 시도해보세요.


참고

profile
기술만 좋은 S급이 아니라, 태도가 좋은 A급이 되자

0개의 댓글

관련 채용 정보