static contextType 를 사용하여 Context 사용하기

이 방식은 2018년 10월 23일에 업데이트된 v16.6 이상 버전에서만 사용 가능합니다.

리액트 컴포넌트에서 Context 를 사용하기위해서, Consumer 를 사용해왔었는데, 이를 조금 더 편하게 사용하기 위해서 HoC 도 직접 만들어보기도 하고 써드파티 라이브러리 안에 들어있는 이미 만들어진 HoC 를 사용해서 구현하기도 했습니다.

최근 리액트 업데이트에선 static contextType 값을 설정하여 컴포넌트에서 Context 를 받아올 수 있는 기능이 도입되었습니다.

먼저 주의해야 할 사항이 두가지가 있는데요

  1. 클래스 컴포넌트에서만 사용 가능
  2. 한 컴포넌트에서 단 하나의 Context 만 사용 할 수 있음

개인적으로 사용성만 따지자면 이걸 사용하는것보다 fromRenderProps 를 사용하는것이 훨씬 편합니다.

한번 직접 사용해볼까요?

another.js 를 열어서 AnotherContext 자체를 default 로 내보내기 해주세요.

src/contexts/another.js

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

const AnotherContext = createContext();
export default AnotherContext; // *** default 로 내보내줍니다!

const { Provider, Consumer: AnotherConsumer } = AnotherContext;

class AnotherProvider extends Component {
  state = {
    number: 1
  };
  actions = {
    increment: () => {
      this.setState(({ number }) => ({ number: number + 1 }));
    }
  };
  render() {
    const { state, actions } = this;
    const value = { state, actions };
    return <Provider value={value}>{this.props.children}</Provider>;
  }
}

export { AnotherProvider, AnotherConsumer };

그리고, Counter.js 에서 기존 컴포넌트를 class 형태로 변환하고, static contextType 값을 방금 내보내줬던 AnotherContext 로 설정해주면 됩니다. 그렇게 하고나면, this.context 를 사용해서 AnotherContext 에 접근 할 수 있습니다.

src/Counter.js

import React, { Component } from 'react';
import AnotherContext from '../contexts/another';

class Counter extends Component {
  static contextType = AnotherContext;
  render() {
    return (
      <div>
        <h1>{this.context.state.number}</h1>
        <button onClick={this.context.actions.increment}>더하기</button>
      </div>
    );
  }
}

// 혹은,
// Counter.contextType = AnotherContext
export default Counter;

여기서 조금 더 나아가면, 이렇게 코드를 정리 할 수도 있습니다.

src/Counter.js

import React, { Component } from 'react';
import Context from '../contexts/another';

class Counter extends Component {
  static contextType = Context;
  get number() {
    return this.context.state.number;
  }
  handleClick = () => {
    this.context.actions.increment();
  };
  render() {
    return (
      <div>
        <h1>{this.number}</h1>
        <button onClick={this.handleClick}>더하기</button>
      </div>
    );
  }
}

export default Counter;

성능면에 있어서는 별 차이 없습니다.

static contextType 을 사용하는 방식은, this.context 로 Context 에 접근하기 때문에, 여러 Context 를 사용 할 수 없는 구조입니다. 이 점 꼭 명시하세요!

Edit Context Tutorial

results matching ""

    No results matching ""