[React JS] Context API

 

 

Context API를 활용한 전역 상태 관리 흐름 이해하기

리액트에서 일반적으로 데이터를 관리할 때는 최상위 컴포넌트인 APP의 state에 넣어서 관리한다.

우리가 리액트 프로젝트를 진행하다보면, 사용자 정보나 공통적으로 필요한 함수들을 전역적으로 상태를 관리해야 하는 경우가 생긴다. 이때, 리액트는 컴포넌트 간 데이터를 props로 전달한다. 컴포넌트끼리 이런 데이터를 주고 받기 위해서는 주로 최상위 컴포넌트인 App의 state에 넣어서 관리가 되는 것이다.

일반적인 전역 상태 관리 흐름

만약 위의 사진에서 G 컴포넌트는 전역 상태를 업데이트하고, F와 J 컴포넌트는 업데이트된 상태를 렌더링한다고 가정한다. 이런 경우라면, App 컴포넌트에서는 아래와 같이 상태와 업데이트 함수를 정의해야 할 것이다.

const [value, setValue] = useState("React");
const onSetValue = useCallback(value => setValue(value), []);

 

하지만 위와 같은 상황에서 데이터를 전달할 때 문제점이 발생한다.

App에 작성된 value 값을 F와 J 컴포넌트에 전달하기 위해서는 여러 컴포넌트를 거쳐야 한다.

F 컴포넌트에 App이 지니고 있는 value를 전달하기 위해서는 App -> A -> B -> F로 전달되고, J 컴포넌트는 App -> H -> J를 거쳐야 전달 가능하다.

 

실제 리액트 프로젝트에서는 이보다 더 많은 컴포넌트를 거쳐야 할 상황이 존재할 것이고, 데이터 또한 훨씬 많아질 수 있다. 이런 방식을 계속 사용하다 보면, 유지 보수성도 낮아질 것이다.

 

이런 문제를 해결하고자 Redux 라이브러리, MobX와 같은 상태 관리 라이브러리를 사용하여 전역 상태 관리 작업을 처리한다. 리액트 v16.3 이후에는 Context API가 많이 개선되어 별도 라이브러리를 사용하지 않아도 전역 상태를 쉽게 관리할 수 있게 되었다.

 

Context API를 사용하면 Context를 만들어 한 번에 원하는 값을 받아와 사용할 수 있다.

 

Context API를 활용한 전역 상태 관리 흐름

 

 

 

Context API 사용법

Context 라는 리액트 패키지에서 createContext 함수를 불러와 사용 가능하다.

React Context는 전역 데이터를 담고 있는 하나의 저장 공간이라고 할 수 있다.

아래 코드와 같이 createContext 함수의 파라미터에는 해당 Context의 기본 상태를 지정할 수 있다.

import { createContext } from 'react';

const ColorContext = createContext({ color: 'blue' });

export default ColorContext;

 

 

Consumer로 Context 접근하기

Consumer를 이용해 Context에 저장되어 있는 전역 데이터에 접근할 수 있다.

Context 변화를 구독하는 컴포넌트로, 설정한 값을 불러와야 할 때 사용한다.

 

import ColorContext from '../contexts/color';

const ColorBox = () => {
  return(
    <ColorContext.Consumer>
      {value => (
        <div
          style={{
            width: '100px',
            height: '100px',
            background: value.color,
          }} />
        )}
      </ColorContext.Consumer>
    );
  };
 
 export default ColorBox;

위의 예시는 Consumer를 이용해 ColorContext에서 지정한 기본 상태 값인 color를 조회하여 적용하는 것이다.

 

 

Provider

Context 객체 안에는 Provider라는 컴포넌트가 있다.

컴포넌트 간 공유하고자 하는 값을 value라는 Props로 설정하면 자식 컴포넌트들에서 해당 값에 바로 접근 가능하다.

Provider를 사용해 Context의 value를 변경 가능하다.

 

import ColorBox from './components/ColorBox';
import ColorContext from './contexts/color;

const App = () => {
  return(
    <ColorContext.Provider value={{color: 'red'}}>
      <div>
        <ColorBox />
      </div>
    </ColorContext.Provider>
  );
};

export default App;

 

우리는 앞서 createContext 함수를 사용할 때, 파라미터로 Context의 기본값을 넣어주었다.

이 기본값은 Provider를 사용하지 않았을 때만 사용된다. 

만약 Provider를 사용하였지만 value를 명시하지 않으면, 기본 값을 사용하지 않은 것이기 때문에 오류가 발생한다.

 

import ColorBox from './components/ColorBox';
import ColorContext from './contexts/color;

const App = () => {
  return(
    <ColorContext.Provider>
      <div>
        <ColorBox />
      </div>
    </ColorContext.Provider>
  );
};

export default App;

위와 같이 Provider를 사용하고 value를 명시하지 않았다면 오류가 발생할 것이다.

 

Provider를 사용할 때는 value를 명시해야 작동되는 것을 명심해야 한다.

 

반응형