[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를 사용하지 않 굳이 이 라이브러리를 사용하는 이유는 무엇일까요?
- Context는 상태 값을 제공하는데 집중한 기능입니다. 실질적으로 업데이트는 useState를 통해 이루어지며, 단순히 값을 제공하는 반면, Redux와 같은 여러 상태 관리 라이브러리는 내부 기능을 통한 유연한 상태 관리가 가능합니다.
- Context는 Provider로 컴포넌트를 감싸줍니다. 이는 종속적으로 값을 사용하는 것인데, Context의 value값이 바뀌게 되는 경우, 내부 컴포넌트들은 새로 렌더링됩니다. 즉 drilling을 사용하지 않을 뿐이지, 행동 자체는 drilling과 다를게 없다는 것입니다.
요약해보자면
- Context API는 단순한 상태 공유 및 전역 상태 관리에 적합하다
- 복잡한 상태 및 로직을 가진 대규모 애플리케이션에서는 상태 관리 라이브러리를 사용하자.