본문 바로가기

HTML + JAVASCRIPT + CSS/ReactJS+AngularJS +VueJS

Context API

728x90

 


Context API

리액트 프로젝트에서 전역적으로 사용할 데이터가 있을 때 유용한 기능입니다.
사용자 로그인 정보, 애플리케이션 환경 설정, 테마 등 여러 종류의 전역 데이터 관리시 사용합니다.
또한 리덕스, 리액트 라우터, styled-components등의 라이브러리는 Context API를 기반으로 구현되어 있습니다.


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

리액트 애플리케이션은 컴포넌트 간의 데이터를 props로 전달하기 대문에 컴포넌트 여기저기서 필요한 데이터가 있을 때는 주로 최상위 컴포넌트에서 state를 이용하여 관리 합니다.

최상위 컴포넌트에서 props로 state를 하위 컴포넌트까지 전달해야 하기 때문에 구조가 복잡해집니다. 실제 리액트프로젝트에서는 더 많은 컴포넌트를 거쳐야 할 때도 있고 다루어야 하는 데이터가 훨씬 많아질 수도 있으므로 이런 방식을 사용하면 유지보수성이 낮아집니다.

따라서 리덕스나 MobX 같은 상태 관리 라이브러리를 사용하여 전역 상태 관리작업을 더욱 편하게 처리하기도 합니다. v16.3 업데이트 이후에는 Context API가 많이 개선되어 별도의 라이브러리를 사용하지 않아도 전역 상태를 손쉽게 관리할 수 있습니다.


state를 이용한 상태 관리

APP의 state를 하위 컴포넌트로 전달하여 상태 관리

bg right w:90%


Context를 이용한 상태 관리

Context API를 이용하여 전역 상태 관리

bg right w:90%


Context API 예제

Context 생성

import { createContext } from 'react';

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

export default ColorContext;

Consumer 사용 (ColorBox 컴포넌트)

색상을 props로 받아오는 것이 아니라 Context 안에 있는 Consumer라는 컴포넌트를 이용해서 조회 합니다.

import React from 'react';
import ColorContext from './context';

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

Provider 사용

Context의 value를 변경하기 위해서는 Provider를 사용하면 됩니다.

import React from 'react';
import ColorBox from './ColorBox';
import ColorContext from './context';
export default () => {
  return (
    <ColorContext.Provider value={{color: 'red' }}>
      <ColorBox />
    </ColorContext.Provider>
  );
}

동적 Context 사용하기

import React, { createContext, useState } from 'react';

const ColorContext = createContext({ 
    state: { color: 'red' }, 
    action: { setColor: () => {} }
  });
const ColorProvider = ({ children }) => {
  const [color, setColor] = useState('red');
  const value = { state: {color}, action: {setColor} };
  return <ColorContext.Provider value={value}>{children}</ColorContext.Provider>;
}
const { Consumer: ColorConsumer } = ColorContext;
// Provider, Consumer 내보내기
export { ColorProvider, ColorConsumer };
export default ColorContext;

동적 Provider 설정

import React from 'react';
import ColorBox from './ColorBox';
import { ColorProvider } from './context';
export default () => {
  return (
    <ColorProvider>
      <ColorBox />
    </ColorProvider>
  );
}

동적 Consumer 설정

import React from "react";
import { ColorConsumer } from "./context";

export default () => {
  return (
    <ColorConsumer>
      {({ state, action }) => (
        <>
          <div
            style={{
              with: "100px",
              height: "80px",
              background: state.color
            }}
          />
          <button onClick={() => action.setColor("blue")}>blue</button>
        </>
      )}
    </ColorConsumer>
  );
};

동적 Context 예제 바로가기


Consumer 대신 Hook 사용하기

import React, { useContext } from "react";
import ColorContext from "./context";
export default () => {
  const { state, action } = useContext(ColorContext);
  return (
      <>
        <div
          style={{
            with: "100px",
            height: "80px",
            background: state.color
          }}
        />
        <button onClick={() => action.setColor("blue")}>blue</button>
      </>
  );
};

마치며

컴포넌트 간에 상태를 교류해야 할 때 무조건 부모 ==> 자식 흐름으로 props를 통해 전달해주었는데 Context API를 통해 더욱 쉽게 상태를 교류할 수 있습니다.

전역적으로 여기저기 사용되는 상태가 있고 컴포넌트의 개수가 많은 상황이라면 Context API를 사용하는 것을 권장합니다.