Context
- context API는 리액트 내장 기능
- 컴포넌트 트리 전체에 걸쳐 데이터를 공유하는 방법
- 일반적으로 리액트에서 데이터를 전달하기 위해서는 부모 → 자식으로 props 통해 전달

- 컴포넌트 수가 많은 대형 프로젝트에서는 props를 많이 사용하는 경우 발생
- context API를 사용하면 중간 컴포넌트들을 건너뛰고 데이터를 직접 전달 ⭕
- context를 사용하는 경우
- 어플리케이션 전체에서 필요한 데이터 (ex: 사용자 정보, 테마 설정)
- 여러 컴포넌트들에 전달되는 반복적인 데이터
- 전역적으로 access가 필요한 데이터
createContext
- 초기 값을 받아 context 객체 생성
- createContext( )는 provider와 consumer 두 개의 리액트 컴포넌트 반환
- provider : 현재의 context 값을 위한 컴포넌트
- consumer : context에 접근하기 위한 컴포넌트
import { createContext } from "react";
const MyContext = createContext({
language: "",
setLanguage: () => {},
});
export default MyContext;
- 초기값 설정 ❌ 타입 설정 ⭕
- createContext 내부에 타입을 설정하는 것은 필수가 아닌 옵션! But, 명시하는 것이 좋음
Provider
- context에 값을 제공
- value prop을 사용하여 값을 전달
- provider에 의해 제공된 값을 하위 컴포넌트들이 사용할 수 있게 됨
- onClick 등에 적용되는 함수는 provider에 넣는 것이 깔끔함
import { useState } from "react";
import MyContext from "./store/lang-context";
export default function LangProvider(props) {
const [language, setLanguage] = useState("ko");
return (
<MyContext.Provider value={{ language, setLanguage }}>
{props.children}
</MyContext.Provider>
);
}
Consumer
- context 값을 사용하는 첫 번째 방법
- consumer의 자식 컴포넌트는 1개
- 자식으로 오는 최상위가 1개여야 함
- 자식의 자식으로 여러 개 컴포넌트 사용은 ⭕
import { useContext } from "react";
import MyContext from "./store/lang-context";
export default function LangSelector() {
return (
<MyContext.Consumer>
{(value) => {
return (
<div>
<h2>현재 선택된 언어 : {value.language}</h2>
<select
value={value.language}
onChange={(e) => value.setLanguage(e.target.value)}
>
<option value="ko">한국어</option>
<option value="jp">일본어</option>
<option value="en">영어</option>
</select>
</div>
);
}}
</MyContext.Consumer>
);
}
useContext
- context 값을 사용하는 두 번째 방법
- useContext Hook을 사용하여 consumer보다 더 간결하게 context 값을 가져옴
import { useContext } from "react";
import MyContext from "./store/lang-context";
export default function LangSelector() {
const value = useContext(MyContext);
return (
<div>
<h2>현재 선택된 언어 : {value.language}</h2>
<select
value={value.language}
onChange={(e) => value.setLanguage(e.target.value)}
>
<option value="ko">한국어</option>
<option value="jp">일본어</option>
<option value="en">영어</option>
</select>
</div>
);
}
🚨 context 사용 시 주의사항
- 재렌더링의 문제
- 하나의 context에 여러 데이터 저장
→ context의 일부가 변경되더라도 해당 context를 사용하는 모든 컴포넌트들이 재렌더링
→ 비효율적
- 중첩된 provider
- 서로 다른 값을 여러 레벨의 컴포넌트에 제공하기 위해서는 provider 중첩 사용하는 경우 발생
→ 코드 복잡도 ↑
- 전역 상태 관리의 복잡성
- 복잡한 어플리케이션에서 전역 상태 관리를 단순히 context API만으로 처리
→ 상태 업데이트 로직이 복잡해질 수 있음
→ Redux 사용하여 해결
reduce 함수
const totalPrice = cart.reduce((acc, curr) => acc + curr.price, 0);