1. State Management(์ํ๊ด๋ฆฌ)
14์์ ์ด Context ๋ณต์ต
1.1 Prop Drilling (Props๋ก๋ง ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋ฉด ๋ฐ์ํ๋ ๋ฌธ์ )

Prop Drilling= Props๋ก๋ง ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋ฉด ๋ฐ์ํ๋ ๋ฌธ์
์ผ๋ฐ์ ์ผ๋ก ์ปดํฌ๋ํธ์๊ฒ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํด์ฃผ์ด์ผ ํ ๋ Props๋ฅผ ํตํด ์ ๋ฌํฉ๋๋ค.
1export default function App() {2return <GrandParent value="Hello World!" />3}45function Parent({ value }) {6return <Child value={value} />7}89function Child({ value }) {10return <Message value={value} />11}1213function Message({ value }) {14return <div>Received: {value}</div>15}
๊ทธ๋ฐ๋ฐ ์์์ด ๋ง์ ์ปดํฌ๋ํธ์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํด์ผ ํ๋ ๊ฒฝ์ฐ, ์ฌ๋ฌ ์ปดํฌ๋ํธ๋ฅผ ๊ฑฐ์ณ ์ฐ๋ฌ์์ Props๋ฅผ ์ค์ ํด์ฃผ์ด์ผ ํ๊ธฐ ๋๋ฌธ์ ๋ถํธํ๊ณ ์ค์ํ ์ ์๋ ๊ฐ๋ฅ์ฑ์ด ์กด์ฌํฉ๋๋ค. ์ด๋ ๊ฒ ๋ง์ ์์์ ๊ฐ์ง ์ปดํฌ๋ํธ์ state๊ฐ์ ์ ๋ฌํ๋ ค๋ฉด Context๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค.
Context API (๋ฆฌ์กํธ ๊ธฐ๋ณธ ๋ฌธ๋ฒ)
- props ์ ์ก์์ด state ๊ณต์ ๊ฐ๋ฅ
- 2๊ฐ์ง ๋ฌธ์ ๋๋ฌธ์ ๋ง์ด ์ฐ์ด์ง ์์
- state ๋ณ๊ฒฝ์ ์ธ๋ฐ์๋ ์ปดํฌ๋ํธ๊น์ง ์ ๋ถ ์ฌ๋ ๋๋ง๋์ด ์ฑ๋ฅ ์ด์
- ์ปดํฌ๋ํธ ์ฌํ์ฉ์ด ์ด๋ ค์
- Context API๋ณด๋ค๋ redux๊ฐ์ ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ง์ด ์ฌ์ฉ
- Official React Context Docsโ๏ธ
2. Context API
-
๋ฆฌ์กํธ ๊ธฐ๋ณธ ๋ฌธ๋ฒ
-
context = state ๋ณด๊ดํจ -
props ์์ด state ๊ณต์ ํ ๋ ์ฌ์ฉํ์ง๋ง, ์ฑ๋ฅ๊ณผ ์ฌํ์ฉ ๊ด์ ์์ ๋ฌธ์ ๊ฐ ์์ด์ ๋ง์ด ์ฌ์ฉ ์ํจ
- state ๋ณ๊ฒฝ์ ์ธ๋ฐ์๋ ์ปดํฌ๋ํธ๊น์ง ์ ๋ถ ์ฌ๋ ๋๋ง๋์ด ์ฑ๋ฅ ์ด์
- useContext()๋ฅผ ์ฐ๊ณ ์๋ ์ปดํฌ๋ํธ๋ ๋์ค์ ๋ค๋ฅธ ํ์ผ์์ ์ฌ์ฌ์ฉํ ๋ Context๋ฅผ import ํ๋๊ฒ ๊ท์ฐฎ์
-
์ ๋ฌธ์ ๋ค๋ก ์ธํด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํจ
-
React v16.3๋ถํฐ ์ฌ์ฉํ๊ธฐ ์ฝ๊ฒ ๋ง์ด ๊ฐ์ ๋จ
- ๊ณผ๊ฑฐ์๋ ๋ฆฌ์กํธ์ Context๊ฐ ๊ต์ฅํ ๋ถํธํด์ ์ ์ญ ์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์์
- ์ด์ ๋ Context๋ฅผ ์ฌ์ฉํ๊ธฐ ํธํด์ ธ์ ๋จ์ํ ์ ์ญ์ ์ธ ์ํ๋ฅผ ๊ด๋ฆฌํ๊ธฐ ์ํจ์ด๋ผ๋ฉด ๋ ์ด์ ์ฌ์ฉํด์ผ ํ ์ด์ X
- ๊ทธ๋ ์ง๋ง ์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์ํ ๊ด๋ฆฌ๋ฅผ ๋์ฑ ํธํ๊ณ , ํจ์จ์ ์ผ๋ก ํ ์ ์๊ฒ ํด์ฃผ๋ ๊ธฐ๋ฅ๋ค์ ์ ๊ณต
-
Redux, ๋ฆฌ์กํธ ๋ผ์ฐํฐ, styled-components ๋ฑ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค์ Context API๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๊ตฌํ๋์ด ์์
-
์ค์ฒฉํด์ ์ฌ์ฉํ ์ปดํฌ๋ํธ๊ฐ ๋ง์ ๋ ํธ๋ฆฌํ ๋ฌธ๋ฒ
- e.g. ๋ก๊ทธ์ธํ ์ ์ ์ ๋ณด, ํ ๋ง(๋คํฌ ํ ๋ง), ์ ํธํ๋ ์ธ์ด ๋ฑ
-
Context์์ ๋ค๋ฃจ๋ ๊ฐ์ ๊ผญ ์ ์ญ์ ์ผ ํ์๊ฐ ์์ต๋๋ค.
- Context๋ ์ฌ์ฌ์ฉ์ฑ์ด ๋์ ์ปดํฌ๋ํธ๋ฅผ ๋ง๋ค๋๋ ๋งค์ฐ ์ ์ฉํจ
-
์ค์ฒฉ๋ ์ปดํฌ๋ํธ๊ฐ ์ ์ผ๋ฉด ๊ทธ๋ฅ props์ฐ๋๊ฒ ํธํจ
-
c.f. Velog - ๋ค๋ฅธ ์ฌ๋๋ค์ด ์ ์๋ ค์ฃผ๋ ๋ฆฌ์กํธ์์ Context API ์ ์ฐ๋ ๋ฐฉ๋ฒ
-
cf. Velopert - Velog ๋ฆฌ์กํธ์์ Context API ์ ์ฐ๋ ๋ฒ
2.1 ์์ 1 : Context ๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ
1import { createContext, useContext } from 'react'23// 1. Context ๋ง๋ค๊ธฐ4// - createContext()๋ก Context ๋ง๋ค ์ ์์5// - ๊ธฐ๋ณธ ๊ฐ์ ์ค์ ํ๊ณ ์ถ๋ค๋ฉด, createContext ํจ์์ ์ธ์๋ก ๊ธฐ๋ณธ ๊ฐ์ ๋ฃ์ด์ฃผ๋ฉด ๋จ6const MyContext = createContext('๊ธฐ๋ณธ๊ฐ')78export default function App() {9// 2. Context ๊ฐ์ฒด ์์๋ Provider๋ผ๋ ์ปดํฌ๋ํธ๊ฐ ๋ค์ด์์10// Provider ์ปดํฌ๋ํธ์ ๊ณต์ ํ๊ณ ์ ํ๋ ๊ฐ์ value ๋ผ๋ Props๋ก ์ค์ ํ๋ฉด,11// ์์ ์ปดํฌ๋ํธ๋ค์์ ํด๋น ๊ฐ์ ๋ฐ๋ก ์ ๊ทผ ๊ฐ๋ฅ12return (13<>14<MyContext.Provider value="Hello World">15<Parent />16</MyContext.Provider>17<Parent />18</>19)20}2122function Parent() {23return <Child />24}2526function Child() {27return <Message />28}2930function Message() {31// 3. Context ์์ ์๋ state ์ฌ์ฉํ๋ ค๋ฉด, useContext() ์ฌ์ฉ32// - useContext() : Context ํด์ฒดํด์ฃผ๋ ํจ์, ๊ณต์ ํ๋ ๋ชจ๋ state๊ฐ ๋ด๊ฒจ์์33const value = useContext(MyContext)34return <div>๋ฐ์ดํฐ ๋์ฐฉํจ!๐ : {value}</div>35}
2.2 ์์ 2 : Dark Theme
2.2.1 Context ์์ฑ
1// Context/ThemeContext.js2import React from 'react'34export const themes = {5light: {6foreground: '#000000',7background: '#eeeeee',8},9dark: {10foreground: '#ffffff',11background: '#222222',12},13}1415// createContext()๋ก Context ๋ง๋ค ์ ์์16export const ThemeContext = React.createContext(themes.dark)
์ Context๋ฅผ ๋ง๋ค ๋๋ createContext ํจ์๋ฅผ ์ฌ์ฉํฉ๋๋ค. ํ๋ผ๋ฏธํฐ์๋ ํด๋น Context์ ๊ธฐ๋ณธ ์ํ๋ฅผ ์ง์ ํฉ๋๋ค.
- c.f. Context๋ฅผ ๋ง๋ค ๋ ๋ฐ๋์ contexts ๋๋ ํฐ๋ฆฌ์ ๋ง๋ค ํ์๋ ์์ต๋๋ค. ๊ฒฝ๋ก๋ ๋ง์๋๋ก ์ ํด๋ ๋จ
2.2.2 Provider
1// Context/Example2import React, { Component } from 'react'3import ThemeButton from './ThemeButton'4import { ThemeContext, themes } from './ThemeContext'56export default class Example extends Component {7constructor(props) {8super(props)9this.state = {10theme: themes.light,11}12this.toggleTheme = () => {13this.setState(prev => ({14theme: prev.theme === themes.dark ? themes.light : themes.dark,15}))16}17}18render() {19// ๐ Context์ ์ ์ฅ๋ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด, Context์ Provider๋ฅผ ์ฌ์ฉ20// - ๊ณต์ ๋ฅผ ์ํ๋ state๋ฅผ value ์์ ์ ์ด์ฃผ๋ฉด ๋ฉ๋๋ค.21// - ThemeContext๋ก ๊ฐ์ผ ๋ชจ๋ ์ปดํฌ๋ํธ์ ๊ทธ ์์์ปดํฌ๋ํธ๋ state๋ฅผ props ์ ์ก์์ด ์ง์ ์ฌ์ฉ๊ฐ๋ฅ22// ๐ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ๋ ค๋ ์ปดํฌ๋ํธ์์ Context์ Consumer๋ฅผ ์ฌ์ฉ โ useContext()๋ก ๋์ฒด ๊ฐ๋ฅ23return (24<div>25<ThemeContext.Provider value={this.state.theme}>26<ThemeButton changeTheme={this.toggleTheme} />27<ThemeContext.Consumer>28{theme => (29<div30style={{31height: 300,32width: 300,33backgroundColor: theme.background,34}}35></div>36)}37</ThemeContext.Consumer>38</ThemeContext.Provider>39<ThemeButton />40</div>41)42}43}
2.2.3 useContext()
1// context/ThemeButton.jsx2import React, { useContext } from 'react'3import { ThemeContext } from './ThemeContext'45export default function ThemeButton(props) {6// Context ์์ ์๋ state ์ฌ์ฉํ๋ ค๋ฉด7// (1) ๋ง๋ค์ด๋ Context๋ฅผ import8// (2) useContext() ์์ ๋ฃ๊ธฐ9// -- useContext()๋ Context ํด์ฒดํด์ฃผ๋ ํจ์, ๊ณต์ ํ๋ ๋ชจ๋ state๊ฐ ๋ด๊ฒจ์์10const theme = useContext(ThemeContext)11return (12<button13{...props}14onClick={props.changeTheme}15style={{ backgroundColor: theme.background, color: theme.foreground }}16>17๋ฒํผ18</button>19)20}
App ์ปดํฌ๋ํธ์ ์ถ๊ฐ
1import Example from './components/3-10_Context/Example'23export default function App() {4return (5<>6<Example />7</>8)9}
[์ฐธ๊ณ ]
- React Context ์ฌ์ฉ๋ฒ : https://www.daleseo.com/react-context/
- Context ํ๊ตญ ๊ณต์๋ฌธ์