
Context API일반적으로 리액트는 부모 컴포넌트에서 자식 컴포넌트로만 데이터를 전달 할 수 있다. 그래서 조상 컴포넌트가 데이터를 자손 컴포넌트로 보내기 위해서는 여러 컴포넌트를 거쳐거쳐 전달할 수 밖에 없었다. 이 깊이가 너무 깊어지면 prop drilling현상이 일어나게 된다. 이 현상은 prop이 어떤 컴포넌트로부터 왔는지 파악을 어렵게 하고, 따라서 오류가 발생할 경우 추적이 힘들어져 대처가 늦을 수 있다.
그래서 react context API라는 개념이 등장하게 된다. 이를 이용하면 상위 컴포넌트의 데이터를 프롭 드릴링 없이 하위 컴포넌트로 보낼 수 있게 된다. 마치 전역변수처럼 느껴질 순 있지만, 전역 데이터는 아니다.
createContext : context 생성useContext: 원하는 context를 구독하고 해당 context의 현재 값 가져오기Provider: context를 하위 컴포넌트에 전달Context API 사용하기// ./context/FamilyContext.js
import { createContext } from "react";
export const FamilyContext = createContext(null); // 초기값을 null로 설정
// ./GrandFather.jsx
import React from "react";
import Father from "./Father";
import { FamilyContext } from "../context/FamilyContext";
function GrandFather() {
const houseName = "HomeSweetHome";
const pocketMoney = 10000;
return (
// FamilyContext 태그 안에 있는 컴포넌트는 FamilyContext라는 맥락을 가진다!
// value는 객체. createContext의 값을 대체한다(현재 초기값 null을 대체한다.)
// Provider를 통해 context를 하위 컴포넌트에 전달
<FamilyContext.Provider value={{ houseName, pocketMoney }}>
<Father />
</FamilyContext.Provider>
);
}
export default GrandFather;
// ./Father.jsx
import React from "react";
import Child from "./Child";
// props가 없다!!
function Father() {
return <Child />;
}
export default Father;
// ./Child.jsx
import React, { useContext } from "react";
import { FamilyContext } from "../context/FamilyContext";
function Child({ houseName, pocketMoney }) {
const stressedWord = {
color: "red",
fontWeight: "900",
};
// useContext를 이용하여 사용할 맥락을 가져온다.
const data = useContext(FamilyContext);
console.log("data", data); // { houseName: "HomeSweetHome", pocketMoney: 10000 }
return (
<div>
<br />
할아버지가 우리 집 이름은 <span style={stressedWord}>{data.houseName}</span>
라고 하셨어요.
<br />
게다가 용돈도 <span style={stressedWord}>{data.pocketMoney}</span>원만큼이나
주셨답니다.
</div>
);
}
export default Child;
데이터의 흐름을 살펴보면 :
GrandFather.jsx에서 Context로 데이터를 업데이트하고 Child.jsx에서 그 데이터를 받았다.
Provider에서 제공한 value가 변하면 useContext를 사용하고 있는 모든 컴포넌트가 리렌더링 된다. 메모이제이션을 통해 이런 리렌더링을 제어할 수도 있다.