Context에 있는 값을 사용할 때 Consumer 대신 다른 방식을 사용하여 값을 받아 오는 방법을 알아보자!
리액트에 내장되어 있는 Hooks 중에서 useContext라는 Hook을 사용하면, 함수형 컴포넌트에서 Context를 아주 편하게 사용
할 수 있다.
import React, { useContext } from "react";
import { ColorConsumer } from "../contexts/color";
// import ColorContext from "../contexts/color";
const ColorBox = () => {
console.log("ColorBox 리렌더링됨");
const { state } = useContext(ColorContext);
return (
// <ColorConsumer>
//{(value) => (
<>
<div
style={{
width: "64px",
height: "64px",
background: value.state.color,
}}
/>
<div
style={{
width: "32px",
height: "32px",
background: value.state.subColor,
}}
/>
</>
// )}
// </ColorConsumer>
);
};
export default ColorBox;
만약 children에 함수를 전달하는 Render Props 패턴이 불편하다면, useContext Hook을 사용해 훨씬 편하게 Context 값을 조회할 수 있다.
하지만 Hook은 함수형 컴포넌트에서만 사용할 수 있음! (클래스형 컴포넌트에서는 Hook 사용 불가능)

기존 작성했던 SelectColors 컴포넌트에 책을 보며 코드를 추가했다. 그런데 static 부분에서 오류가 발생!!!

그렇다고 한다....
기존 함수형 SelectColors 컴포넌트를 클래스형 컴포넌트로 바꿔주도록 하자!
import React from "react";
import ColorConsumer from "../contexts/color";
const colors = ["red", "orange", "yellow", "green", "blue", "indigo", "violet"];
// static contextType => 클래스 컴포넌트에서만 사용 가능
// 컴포넌트 내부에서 context를 사용하기 위해 사용
class SelectColors extends Component {
static contextType = ColorContext;
render() {
return (
<div>
<h2>색상을 선택하세요.</h2>
<div style={{ display: 'flex' }}>
{colors.map(color => (
<div
key={color}
style={{
background: color,
width: '24px',
height: '24px',
cursor: 'pointer'
}}
/>
))}
</div>
<hr />
</div>
);
}
}
export default SelectColors;
이렇게 하면 this.context를 조회했을 때 현재 Context의 value를 가리키게 됨.
만약 setColor를 호출하고 싶다면? this.context.actions.setColor를 호출하면 됨!
import React from "react";
import ColorConsumer from "../contexts/color";
const colors = ["red", "orange", "yellow", "green", "blue", "indigo", "violet"];
// static contextType 값 지정
// 클래스 컴포넌트에서만 사용 가능
// 컴포넌트 내부에서 context를 사용하기 위해 사용
class SelectColors extends Component {
static contextType = ColorContext;
// SetColor, SetSubcolor 호출하려면?
handleSetColor = (color) => {
// this.context 조회 -> 현재 Context의 value를 가르킴
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",
}}
/>
))}
</div>
<hr />
</div>
);
}
}
export default SelectColors;
✅ static contextType 정의 시, 장단점
- 장점
클래스 메서드에서도 Context에 넣어 둔 함수를 호출할 수 있음.
프로젝트의 컴포넌트 구조가 꽤 간단하고 다루는 상태의 종류가 그다지 많지 않다면, 굳이 Context를 사용할 필요는 없지만, 전역적으로 여기저기서 사용되는 상태가 있고 컴포넌트의 개수가 많다면 Context API를 사용하는 것을 권장함!
- 단점
한 클래스에서 하나의 Context밖에 사용하지 못함.
그러나 앞으로 새로운 컴포넌트를 작성할 때 클래스형으로 작성하는 일은 많지 않기 때문에 useContext를 사용이 권장됨.