본문 바로가기

Web Front-End/React

React Context API

1. Context API

  • Context API는 리액트 프로젝트에서 전역으로 사용할 데이터가 있을 때 유용한 기능
  • Vue에 Vuex가 존재하는 것처럼 리액트에서는 Redux, MobX 같은 상태 관리 라이브러리를 사용하여 전역 상태 관리 작업을 처리한다.
  • v16.3 업데이트 이후 Context API가 많이 개선되었기 때문에 별도의 라이브러리를 사용하지 않아도 전역 상태를 손쉽게 관리할 수 있다.
  • 음.. Vue의 EventBus 같은 기능인가??
  • 새로운 Context를 만드려면 react의 createContext 함수를 사용해야하고 파라미터로는 해당 Context의 기본 상태를 지정한다.

2. Customer

  • Customer를 통해 props 같은 상태 값을 가져온다.
const ColorBox = () => {
  return (
    <ColorContext.Consumer>
      {(value) => (
        <div
          style={{
            width: "64px",
            height: "64px",
            background: value.color,
          }}
        ></div>
      )}
    </ColorContext.Consumer>
  );
};

 

3. Provider

  • Provider를 사용하면 Context의 value를 수정할 수 있다.
  • Provider를 사용할 때는  value 값을 반드시 명시해야한다.
  • state, action 을 따로 분리하는게 좋고 createContext의 기본 값과 Provider에 들어가는 value의 값의 형태를 일치시켜주는게 좋다.
    <ColorContext.Provider value={{ color: "red" }}>
      <div>
        <ColorBox />
      </div>
    </ColorContext.Provider>

 

4. useContext

  • 리액트에 내장되어 있는 Hooks 중에 useContext라는 Hook을 사용하면, 함수형 컴포넌트에서 Context를 쉽게 사용할 수 있다. ( 클래스형에서는 불가)
import React, { useContext } from "react";
import ColorContext, { ColorConsumer } from "../contexts/color";
//import ColorContext from "../contexts/color";

const ColorBox = () => {
  const { state } = useContext(ColorContext);

  return (
    <div>
      <div>
        <div
          style={{
            width: "64px",
            height: "64px",
            background: state.color,
          }}
        ></div>
        <div
          style={{
            width: "32px",
            height: "32px",
            background: state.subcolor,
          }}
        ></div>
      </div>
    </div>
  );
};

export default ColorBox;
  • 클래스형으로 contextAPI를 쉽게 사용하기 위해서는 "static contextType" 을 사용해야한다.
  • static context로 지정한 후 접근은 this.context로 한다.
  • this.context로 Context에 넣어 둔 함수를 호출할 수 있다.
  • 단점으로.. 하나의 클래스에서 하나의 Context밖에 사용할 수 없다....(치명적인데??)
  • 함수형 컴포넌트를 사용하는게 권장사항이라 함수형컴포넌트의 useContext를 사용할것을 권장한다고 한다.
import React, { Component } from "react";
import ColorContext, { ColorConsumer } from "../contexts/color";

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

class SelectColors extends Component {
  static contextType = ColorContext;

  handleSetColor = (color) => {
    this.context.actions.setColor(color);
  };

  handleSetSubColor = (subcolor) => {
    this.context.actions.setSubcolor(subcolor);
  };

  render() {
    return (
      <div>
        <h2>색상을 선택하세요</h2>
        <div style={{ display: "flex" }}>
          {colors.map((color) => (
            <div
              key={color}
              style={{
                background: color,
                width: "24px",
                height: "24px",
                cursor: "pointer",
              }}
              onClick={() => this.handleSetColor(color)}
              onContextMenu={(e) => {
                e.preventDefault();
                this.handleSetSubColor(color);
              }}
            ></div>
          ))}
        </div>
      </div>
    );
  }
}

export default SelectColors;

 

개인적으로 Vuex같은 상태관리를 전역에서 관리하는 라이브러리를 사용하면 편하고 좋을거 같지만(물론 구현당시엔 편하다...) 프로젝트 규모가 작은 경우에는 상관없지면 규모가 커질 수록 오히려 햇갈려서 오류가 발생하면 어디서부터 봐야할지 난감한거같다. 로그인 사용자 정보나.. 진짜 전역에서 관리해야하는 값이 아니라면 props로 주고 받고 진짜 컴포넌트로써의 역할을 갖는게 컴포넌트로써의 의미가 있고 코드가 깔끔해지는거 같다..

내 기준을 세우면.. 부모자식간에 상태교류는 부모 -> 자식 에 props를 통해 전달하는게 가장 깔끔하고 도저히 안되는것들은 context API나 전역상태 라이브러리를 쓰도록하자!

 

 

 

 

 

 

 

 

 

'Web Front-End > React' 카테고리의 다른 글

React 리덕스  (0) 2020.04.19
React Function as a child or Render Props  (0) 2020.04.19
React Router 적용  (0) 2020.04.18
React SPA(Single Page Application)  (0) 2020.04.18
React immer  (0) 2020.04.18