[React] Context를 이용하여 전역에서 사용하는 상태 만들기

 

이번 시간에는 React의 Context를 익히는 시간을 가지려고 합니다.

❓언제 Context를 사용할 수 있을까요?

Context는 전역에 상태를 저장할 수 있습니다.

이는 일일이 컴포넌트에 props를 넘겨주지 않게 해줍니다.

export default function App() {
  const [prop, setProp] = useState()

  return (
    <div>
		<Box prop={prop}/>
    </div>
  );
}
export default function Box({prop}) {
	console.log(prop) // App 부모 요소에서 전달받은 prop 값

  return ...

props을 넘겨주는 예시입니다.

Constext를 사용함으로써 props를 넘겨주지 않아도 됨으로써, 의존성을 없앨 수 있고, drilling을 없애 가독성을 향상시킬 수 있습니다.

✨Context 사용하기

Constext를 만드는 방법은 다음과 같습니다.

import { useState } from "react";

const ThemeContext = createContext();

createContext() 메서드의 인자는 없어도 되고, Default Value를 설정할 수 있습니다.

const ThemeContext = createContext('Default Value');

Default Value를 사용하는 것은 유용하지 않습니다. 상태를 변경할 수 없기 때문입니다.

초기 값을 설정하지 않고 다음과 같이 사용할 수 있습니다.

export const ThemeContext = createContext();

function App() {
  const [theme, setTheme] = useState('light');
  // ...
  return (
    <ThemeContext.Provider value={theme}>
      <Page />
    </ThemeContext.Provider>
  );
}

Provider 컴포넌트로 감싸주게 되면, 내부 자식 요소에서 ThemeContext 값을 사용할 수 있게 됩니다.

✨Context를 이용한 간단한 예시

Context는 유저데이터, 테마, 언어데이터를 사용하기 좋습니다.

아래 예제는 테마를 설정하는 간단한 예시입니다.

// App.js
import "./styles.css";
import SmallBox from "./SmallBox.js";
import { createContext, useState } from "react";

export const ThemeContext = createContext()

export default function App() {
  const [theme, setTheme] = useState('dark')

  const onClick = () => {
    if(theme === 'dark') setTheme('light')
    if(theme === 'light') setTheme('dark')
  }

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <div>
        change Theme
        <button onClick={onClick}>Click!</button>
      </div>
      <ThemeContext.Provider value={theme}>
        <SmallBox/>
      </ThemeContext.Provider>
    </div>
  );
}
// SmallBox.js
import { useContext } from "react";
import { ThemeContext } from "./App.js";

export default function SmallBox() {
    const theme = useContext(ThemeContext);
    
  return (
    <div className={"SmallBox " + theme} >
        Theme is {theme} mode
    </div>
  );
}

 

코드샌드박스에서 예시보기 ↘️

 

https://codesandbox.io/p/sandbox/frosty-framework-v2xc88?file=%2Fsrc%2FSmallBox.js%3A1%2C1-12%2C2

 

codesandbox.io

context를 사용하여 클릭으로 theme를 변경할 수 있게 하였습니다.

 

❓상태 관리 라이브러리와의 차이?

Redux, Recoil, Zustand 등 여러 상태 관리 라이브러리가 있습니다. Context를 사용하지 않 굳이 이 라이브러리를 사용하는 이유는 무엇일까요?

  1. Context는 상태 값을 제공하는데 집중한 기능입니다. 실질적으로 업데이트는 useState를 통해 이루어지며, 단순히 값을 제공하는 반면, Redux와 같은 여러 상태 관리 라이브러리는 내부 기능을 통한 유연한 상태 관리가 가능합니다.
  2. Context는 Provider로 컴포넌트를 감싸줍니다. 이는 종속적으로 값을 사용하는 것인데, Context의 value값이 바뀌게 되는 경우, 내부 컴포넌트들은 새로 렌더링됩니다. 즉 drilling을 사용하지 않을 뿐이지, 행동 자체는 drilling과 다를게 없다는 것입니다.

요약해보자면

  • Context API는 단순한 상태 공유 및 전역 상태 관리에 적합하다
  • 복잡한 상태 및 로직을 가진 대규모 애플리케이션에서는 상태 관리 라이브러리를 사용하자.