static contextType 를 사용하여 Context 사용하기
이 방식은 2018년 10월 23일에 업데이트된 v16.6 이상 버전에서만 사용 가능합니다.
리액트 컴포넌트에서 Context 를 사용하기위해서, Consumer 를 사용해왔었는데, 이를 조금 더 편하게 사용하기 위해서 HoC 도 직접 만들어보기도 하고 써드파티 라이브러리 안에 들어있는 이미 만들어진 HoC 를 사용해서 구현하기도 했습니다.
최근 리액트 업데이트에선 static contextType
값을 설정하여 컴포넌트에서 Context 를 받아올 수 있는 기능이 도입되었습니다.
먼저 주의해야 할 사항이 두가지가 있는데요
- 클래스 컴포넌트에서만 사용 가능
- 한 컴포넌트에서 단 하나의 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 를 사용 할 수 없는 구조입니다. 이 점 꼭 명시하세요!