끄적끄적 코딩
article thumbnail
Published 2023. 6. 30. 05:02
[React] Context API React

Context API는 리액트 프로젝트에서 전역적으로 사용할 데이터가 있을 때 유용하다.
ex) 사용자 로그인 정보, 애플리케이션 환경 설정, 테마 등

Context API는 리액트 관련 라이브러리에서도 많이 사용되고 있다.
ex) 리덕스, 리액트 라우터, styled components 등은 모두 context api를 기반으로 구현된 것이다.

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

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

  • 최상위 컴포넌트인 App의 state에 넣어서 관리한다.
  • 문제점 : 다루어야 하는 데이터의 중복값이 늘어나므로 유지보수성이 낮아질 가능성이 있다.
  • 리액트 v16.3 업데이트 이후에는 Context API가 많이 개선되었기 때문에 별도의 라이브러리를 사용하지 않아도 전역 상태를 쉽게 관리할 수 있다.


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

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

 

Context API 사용법 익히기

크게 createContext, consumer, provider만 알면 된다.

  • createContext : context 객체 생성
  • consumer : context의 변화를 구독하는 컴포넌트
  • provider : Provider 컴포넌트를 통해서 Context의 값을 설정


새 Context 만들기

새로운 Context 생성

  • createContext 함수로 새로운 Context를 생성한다.
  • 파라미터는 초기 상태를 나타낸다.
  • contexts > color.js
import { createContext } from 'react';

const ColorContext = createContext({ color: 'black'}); // context의 기본 상태 

export default ColorContext;


Consumer 사용하기

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

const ColorBox = () => {
  return (
    <ColorContext.Consumer>
			{value => (
				<div
					style={{
					...
					background: value.color
					}}
				/>
			)}
		</ColorContext.Consumer>
};

export default ColorBox;

 

  • App.js
import ColorContext from '../contexts/color';

const ColorBox = () => {
  return (
    <ColorContext.Consumer>
			{value => (
				<div
					style={{
					...
					background: value.color
					}}
				/>
			)}
		</ColorContext.Consumer>
};

export default ColorBox;

15.2.3 Provider

  • Context의 value를 변경하고 싶을때 provider을 사용한다.
  • App.js에서 provider을 사용하여 color의 값을 red로 변경하면 다음과 같다.
import React from 'react';
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를 명시해주지 않으면 에러가 발생한다.

import React from 'react';
import ColorBox from './components/ColorBox';
import ColorContext from "./contexts/color";

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

export default App;

 

동적 Context 사용하기

  • 지금까지는 고정적인 값만 사용할 수 있다.
  • Context의 값을 update 해야하는 경우 어떻게 사용하는지 알아보자.

Context 파일 수정하기

ColorProvider 추가

  • ColorContext.Provider을 렌더링하는 context를 생성한다.
  • 그에 따라서 기존 createContext안에 있는 state와 actions 형태도 변경해준다.
import React, { createContext, useState } from 'react';

const ColorContext = createContext({
  **state: { color: 'black', subcolor: 'red' },
  actions: {
    setColor: () => {},
    setSubcolor: () => {}**
  }
});

const **ColorProvider** = ({ children }) => {
  const [color, setColor] = useState('black');
  const [subcolor, setSubcolor] = useState('red');

  const **value** = {
    state: { color, subcolor }, // 상태
    actions: { setColor, setSubcolor } // 업데이트 함수 
  };

  return (
    **<ColorContext.Provider value={value}>{children}</ColorContext.Provider>**
  );
};

// const ColorConsumer = ColorContext.Consumer과 같은 의미
const { Consumer: ColorConsumer } = ColorContext;

// ColorProvider와 ColorConsumer 내보내기
export { ColorProvider, ColorConsumer };

export default ColorContext;



새로워진 Context를 프로젝트에 반영하기

ColorContext.Provider 에서 ColorProvider로 변경해준다.

import React from 'react';
import ColorBox from './components/ColorBox';
**import { ColorProvider } from './contexts/color';**

const App = () => {
  return (
    **<ColorProvider>**
      <div>
        <ColorBox />
      </div>
    **</ColorProvider>**
  );
};

export default App;

그 아래는 색상 컴포넌트 만들기 실습 (앞의 내용과 동일한 흐름이라 생략)


Consumer 대신 Hook 또는 static contextType 사용하기

  • Context에 있는 값을 사용할 때, consumer을 사용한다.
  • consumer 대신 다른 방식을 사용하여 값을 받아오는 방법을 알아보자.


useContext Hook 사용하기

  • useContext라는 hook을 사용하면, 함수 컴포넌트에서 context를 편하게 사용할 수 있다.
import React, { useContext } from 'react';
import ColorContext from '../contexts/color';

const ColorBox = () => {
  **const { state } = useContext(ColorContext);**
  return (
    <>
      <div
        style={{
          ...
          **background: state.color**
        }}
      />
    </>
  );
};

export default ColorBox;

함수 컴포넌트에서만 사용가능하다. (클래스형 x)


static contextType 사용하기

클래스형 컴포넌트에서 Context를 좀 더 쉽게 사용하고 싶다면 static contextType을 정의한다.

  • static contextType = ColorContext; 라고 써주면 this.context를 조회했을 때 현재 Context의 value를 가리키게 된다.
import React, { Component } from 'react';
import ColorContext from '../contexts/color';

const colors = ['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet'];

class SelectColors extends Component {
  **static contextType = ColorContext;**
  render() {
    return (
      <div>
        ...
      </div>
    );
  }
}

export default SelectColors;

 


정리

  • 기존 부모 → 자식 흐름으로만 props 전달이 가능했지만, Context API를 통해 더욱 쉽게 상태를 교류할 수 있게 되었다.
  • 프로젝트의 규모가 작고 간단하다면 굳이 Context를 사용할 필요는 없지만, 전역적으로 여기저기서 사용되는 상태가 있고, 컴포넌트의 개수가 많은 상황이라면 Context API 사용을 권장한다.

검색 태그