[React] Context API 사용하기
Context API 란?
Context API 는 리액트 프로젝트에서 데이터를 전역적으로 사용할 수 있게 해주는 유용한 리액트 내장 기능이다. 전역적인 데이터는 예를들어 사용자 로그인 정보, 앱 환경 설정 및 테마 등이 있다.
리액트는 기본적으로 부모 컴포넌트에서 자식 컴포넌트로 순차적으로 데이터를 props 로 내려준다. 이렇게 보면 상당히 간단한 개념이지만 프로젝트의 크기가 커지고 기능이 다양해지면 여러개의 컴포넌트들이 부모 자식으로 구성이 돼있는 상태에서 멀리있는 자식 컴포넌트간에 데이터를 props 로 주고받는것은 매우 어려운 일이다. 이럴경우 해당 데이터는 불필요하게 많은 다른 자식 컴포넌트들을 거치게 돼 상당히 코드가 복잡하여 추후 유지 보수에 어려움을 줄 수 있다.
왼쪽 이미지를 통해 상기 문제를 예로 들어보자.
[G] -> [J] 로 데이터를 전달해줄 일이 생겼다고 가정해보자. 그럼 Root 에서 useState 를 구성하고 setter 를 [A] -> [B] -> [E] -> [G] 이렇게 내려줘 데이터 상태값을 set 한다음 값을 다시 props 로 [H] -> [J] 로 내려줘야 한다. 이러면 너무 복잡하고 다른 props 들과 엮여 유지보수에 매우 불리하다. 이런식으로 값을 전달하는걸 props Drilling 이라고 한다.
이러한 문제점들 때문에 Context API 를 사용해 부모 자식간에 props 로 데이터를 전달할 필요 없이 전역으로 데이터를 주고받을 수 있게 처리해준다. [G] 의 데이터를 [Context] 에서 전역으로 관리해 불필요하게 다른 컴포넌트들을 거칠 필요 없이 바로 [J] 에서 가져다 사용할 수 있게 처리를 해준다. 보기에는 너무나도 멋진 기능이다.
Context API 간단 적용해보기
먼저 글자색을 바꾸고 해당 글자색이 무슨색인지 알려주는 로직을 간단하게 구성하여 설명하려 한다.
기본 페이지 구성이다.
src/App.js
import ColorProvider from "./contexts/ColorProvider";
import FirstPage from "./page/FirstPage";
function App() {
return (
<ColorProvider {...{initColor : 'blue'}}>
<FirstPage />
</ColorProvider>
);
}
export default App;
src/context/ColorProvider.js
import React, { createContext, useContext, useState } from 'react';
export const ColorContext = createContext(null);
export const useColorContext = () => {
const colorSet = useContext(ColorContext);
return colorSet;
}
const ColorProvider = ({children, initColor}) => {
const [color, setColor] = useState(initColor);
return (
<ColorContext.Provider value={{color, setColor}}>
{children}
</ColorContext.Provider>
);
};
export default ColorProvider;
createContext() 로 Context 를 만들고 Context.Provider 로 value 를 제공해준다.
src/page/FirstPage.js
import React from 'react';
import { useColorContext } from '../contexts/ColorProvider';
const FirstPage = () => {
const {color, setColor} = useColorContext();
console.log(color)
return (
<div>
<div>현재 글자색은 : {color}</div>
<h1 style={{color : `${color}`}}>색 표현</h1>
<button onClick={() => setColor(color === 'blue' ? 'red' : 'blue')}>
{color === 'blue' ? '빨간색' : '파란색'}으로 교체
</button>
</div>
);
};
export default FirstPage;
버튼을 클릭하면 색이 변한다.
삼항 연산자를 사용해 빨간색과 파란색이 순차적으로 변하도록 하였다.
FirstPage.js 에서는 아무런 props 를 받지 않고 useContext 라는걸 사용해 Context 로 부터 데이터를 받았다.
참고로 useColorContext() 라는 커스텀 hooks 을 정의함으로써 화면단인 FirstPage 에서 useContext 와 ColorContext 를 import 할 필요 없이 깔끔하게 useColorContext() 메서드만 호출해 Context API 에서 전역 데이터를 가져왔다.
참고로 값만 전역으로 관리되는게 아닌 함수 또한 전역으로 관리 된다.
이제 App.js 에 <ColorProvider> 컴포넌트 아래에 생기는 자식 컴포넌트들은 저 color 과 setColor 를 props 로 받을 필요 없이 useColorContext() 메서드로 값 또는 메서드를 전역에서 불러와 사용할 수 있다.