useContext ๋Š” ์ปดํฌ๋„ŒํŠธ์—์„œ context๋ฅผ ์ฝ๊ณ  ๊ตฌ๋…ํ•  ์ˆ˜ ์žˆ๋Š” React Hook์ž…๋‹ˆ๋‹ค.

const value = useContext(SomeContext)

๋ ˆํผ๋Ÿฐ์Šค

useContext(SomeContext)

useContext ๋ฅผ ์ปดํฌ๋„ŒํŠธ์˜ ์ตœ์ƒ์œ„ ์ˆ˜์ค€์—์„œ ํ˜ธ์ถœํ•˜์—ฌ context๋ฅผ ์ฝ๊ณ  ๊ตฌ๋…ํ•ฉ๋‹ˆ๋‹ค.

import { useContext } from 'react';

function MyComponent() {
const theme = useContext(ThemeContext);
// ...

์•„๋ž˜์—์„œ ๋” ๋งŽ์€ ์˜ˆ์‹œ๋ฅผ ํ™•์ธํ•ด๋ณด์„ธ์š”.

๋งค๊ฐœ๋ณ€์ˆ˜

  • SomeContext: createContext ๋กœ ์ƒ์„ฑํ•œ context์ž…๋‹ˆ๋‹ค. context ์ž์ฒด๋Š” ์ •๋ณด๋ฅผ ๋‹ด๊ณ  ์žˆ์ง€ ์•Š์œผ๋ฉฐ, ์ปดํฌ๋„ŒํŠธ์—์„œ ์ œ๊ณตํ•˜๊ฑฐ๋‚˜ ์ฝ์„ ์ˆ˜ ์žˆ๋Š” ์ •๋ณด์˜ ์ข…๋ฅ˜๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

๋ฐ˜ํ™˜๊ฐ’

useContext ๋Š” ํ˜ธ์ถœํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ์— ๋Œ€ํ•œ context ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ฐ’์€ ํŠธ๋ฆฌ์—์„œ ํ˜ธ์ถœํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ ์œ„์˜ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด SomeContext.Provider ์— ์ „๋‹ฌ๋œ value๋กœ ๊ฒฐ์ •๋ฉ๋‹ˆ๋‹ค. provider๊ฐ€ ์—†์œผ๋ฉด ๋ฐ˜ํ™˜๋œ ๊ฐ’์€ ํ•ด๋‹น ์ปจํ…์ŠคํŠธ์— ๋Œ€ํ•ด createContext ์— ์ „๋‹ฌํ•œ defaultValue ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ๋ฐ˜ํ™˜๋œ ๊ฐ’์€ ํ•ญ์ƒ ์ตœ์‹  ์ƒํƒœ์ž…๋‹ˆ๋‹ค. ์ปจํ…์ŠคํŠธ๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด React๋Š” ์ž๋™์œผ๋กœ ํ•ด๋‹น context ๋ฅผ ์ฝ๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋‹ค์‹œ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค.

์ฃผ์˜ ์‚ฌํ•ญ

  • ์ปดํฌ๋„ŒํŠธ ๋‚ด์˜ useContext() ํ˜ธ์ถœ์€ ๋™์ผํ•œ ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฐ˜ํ™˜๋œ provider์— ์˜ํ–ฅ์„ ๋ฐ›์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ•ด๋‹นํ•˜๋Š” <Context.Provider> ๋Š” useContext() ํ˜ธ์ถœ์„ ํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ ์œ„์— ๋ฐฐ์น˜๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • React๋Š” ๋‹ค๋ฅธ value์„ ๋ฐ›๋Š” provider๋กœ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด์„œ ํŠน์ • context๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋“  ์ž์‹๋“ค์„ ์ž๋™์œผ๋กœ ๋ฆฌ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. ์ด์ „ ๊ฐ’๊ณผ ๋‹ค์Œ ๊ฐ’์€ Object.is ๋น„๊ต๋ฅผ ํ†ตํ•ด ๋น„๊ต๋ฉ๋‹ˆ๋‹ค. memo๋กœ ๋ฆฌ๋ Œ๋”๋ง์„ ๊ฑด๋„ˆ๋›ฐ์–ด๋„ ์ž์‹๋“ค์ด ์ƒˆ๋กœ์šด context ๊ฐ’์„ ๋ฐ›๋Š” ๊ฒƒ์„ ๋ง‰์ง€๋Š” ๋ชปํ•ฉ๋‹ˆ๋‹ค.
  • ๋นŒ๋“œ ์‹œ์Šคํ…œ์ด ๊ฒฐ๊ณผ๋ฌผ์— ์ค‘๋ณต ๋ชจ๋“ˆ์„ ์ƒ์„ฑํ•˜๋Š” ๊ฒฝ์šฐ(์‹ฌ๋ณผ๋ฆญ ๋งํฌ์—์„œ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Œ) context๊ฐ€ ์†์ƒ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. context๋ฅผ ํ†ตํ•ด ๋ฌด์–ธ๊ฐ€๋ฅผ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์€ === ๋น„๊ต์— ์˜ํ•ด ๊ฒฐ์ •๋˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ์ปจํ…์ŠคํŠธ๋ฅผ ์ œ๊ณตํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•˜๋Š” SomeContext์™€ context๋ฅผ ์ฝ๋Š” ๋ฐ ์‚ฌ์šฉํ•˜๋Š” SomeContext๊ฐ€ ์ •ํ™•ํ•˜๊ฒŒ ๋™์ผํ•œ ๊ฐ์ฒด์ธ ๊ฒฝ์šฐ์—๋งŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

์‚ฌ์šฉ๋ฒ•

ํŠธ๋ฆฌ์˜ ๊นŠ์€ ๊ณณ์— ๋ฐ์ดํ„ฐ ์ „๋‹ฌํ•˜๊ธฐ

์ปดํฌ๋„ŒํŠธ์˜ ์ตœ์ƒ์œ„ ์ˆ˜์ค€์—์„œ useContext๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ context๋ฅผ ์ฝ๊ณ  ๊ตฌ๋…ํ•ฉ๋‹ˆ๋‹ค.

import { useContext } from 'react';

function Button() {
const theme = useContext(ThemeContext);
// ...

useContext๋Š” ์ „๋‹ฌํ•œ context ์— ๋Œ€ํ•œ context value ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. context ๊ฐ’์„ ๊ฒฐ์ •ํ•˜๊ธฐ ์œ„ํ•ด React๋Š” ์ปดํฌ๋„ŒํŠธ ํŠธ๋ฆฌ๋ฅผ ๊ฒ€์ƒ‰ํ•˜๊ณ  ํŠน์ • context์— ๋Œ€ํ•ด ์ƒ์œ„์—์„œ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด context provider๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค.

context๋ฅผ Button์— ์ „๋‹ฌํ•˜๋ ค๋ฉด ํ•ด๋‹น ๋ฒ„ํŠผ ๋˜๋Š” ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ ์ค‘ ํ•˜๋‚˜๋ฅผ ํ•ด๋‹น context provider๋กœ ๊ฐ์Œ‰๋‹ˆ๋‹ค:

function MyPage() {
return (
<ThemeContext.Provider value="dark">
<Form />
</ThemeContext.Provider>
);
}

function Form() {
// ... ๋‚ด๋ถ€์—์„œ ๋ฒ„ํŠผ์„ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. ...
}

provider์™€ Button์‚ฌ์ด์— ์–ผ๋งˆ๋‚˜ ๋งŽ์€ ์ปดํฌ๋„ŒํŠธ ๋ ˆ์ด์–ด๊ฐ€ ์žˆ๋Š”์ง€๋Š” ์ค‘์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Form ๋‚ด๋ถ€์˜ Button ์ด ์–ด๋””์—์„œ๋‚˜ useContext(ThemeContext)๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด,"dark"๋ฅผ ๊ฐ’์œผ๋กœ ๋ฐ›์Šต๋‹ˆ๋‹ค.

์ฃผ์˜ํ•˜์„ธ์š”!

useContext() ๋Š” ํ•ญ์ƒ ํ˜ธ์ถœํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ ์ƒ์œ„์—์„œ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด provider๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค. ์œ„์ชฝ์œผ๋กœ ์ฐพ๊ณ  useContext()๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ ์•ˆ์˜ provider๋Š” ๊ณ ๋ คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

import { createContext, useContext } from 'react';

const ThemeContext = createContext(null);

export default function MyApp() {
  return (
    <ThemeContext.Provider value="dark">
      <Form />
    </ThemeContext.Provider>
  )
}

function Form() {
  return (
    <Panel title="Welcome">
      <Button>Sign up</Button>
      <Button>Log in</Button>
    </Panel>
  );
}

function Panel({ title, children }) {
  const theme = useContext(ThemeContext);
  const className = 'panel-' + theme;
  return (
    <section className={className}>
      <h1>{title}</h1>
      {children}
    </section>
  )
}

function Button({ children }) {
  const theme = useContext(ThemeContext);
  const className = 'button-' + theme;
  return (
    <button className={className}>
      {children}
    </button>
  );
}


Context๋ฅผ ํ†ตํ•ด ์ „๋‹ฌ๋œ ๋ฐ์ดํ„ฐ ์—…๋ฐ์ดํŠธํ•˜๊ธฐ

๊ฐ€๋”์€ context๊ฐ€ ์‹œ๊ฐ„์ด ์ง€๋‚จ์— ๋”ฐ๋ผ ๋ณ€๊ฒฝ๋˜๊ธฐ๋ฅผ ์›ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. context๋ฅผ ์—…๋ฐ์ดํŠธ ํ•˜๋ ค๋ฉด state์™€ ๊ฒฐํ•ฉํ•˜์‹ญ์‹œ์˜ค. ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์—์„œ state๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•˜๊ณ  ํ˜„์žฌ state๋ฅผcontext value๋กœ provider์— ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.

function MyPage() {
const [theme, setTheme] = useState('dark');
return (
<ThemeContext.Provider value={theme}>
<Form />
<Button onClick={() => {
setTheme('light');
}}>
Switch to light theme
</Button>
</ThemeContext.Provider>
);
}

์ด์ œ provider ๋‚ด๋ถ€์˜ ๋ชจ๋“  Button์€ ํ˜„์žฌ theme ๊ฐ’์„ ๋ฐ›๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. provider์—๊ฒŒ ์ „๋‹ฌ๋œ theme๊ฐ’์„ ์—…๋ฐ์ดํŠธ ํ•˜๊ธฐ ์œ„ํ•ด setTheme์„ ํ˜ธ์ถœํ•˜๋ฉด, ๋ชจ๋“ Button ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ƒˆ๋กœ์šด 'light' ๊ฐ’์œผ๋กœ ๋ฆฌ๋ Œ๋”๋ง ๋ฉ๋‹ˆ๋‹ค.

context ์—…๋ฐ์ดํŠธ ์˜ˆ์‹œ

์˜ˆ์ œ 1 of 5:
Context๋ฅผ ํ†ตํ•ด ๊ฐ’ ์—…๋ฐ์ดํŠธ

์ด ์˜ˆ์‹œ์—์„œ MyApp ์ปดํฌ๋„ŒํŠธ๋Š” state ๋ณ€์ˆ˜๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๊ณ , ์ด state ๋ณ€์ˆ˜๋Š” ThemeContext provider ๋กœ ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค. โ€œDark modeโ€ ์ฒดํฌ๋ฐ•์Šค๋ฅผ ์ฒดํฌํ•˜๋ฉด state๊ฐ€ ์—…๋ฐ์ดํŠธ ๋ฉ๋‹ˆ๋‹ค. ์ œ๊ณต๋œ ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋ฉด ํ•ด๋‹น context๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฆฌ๋ Œ๋”๋ง ๋ฉ๋‹ˆ๋‹ค.

import { createContext, useContext, useState } from 'react';

const ThemeContext = createContext(null);

export default function MyApp() {
  const [theme, setTheme] = useState('light');
  return (
    <ThemeContext.Provider value={theme}>
      <Form />
      <label>
        <input
          type="checkbox"
          checked={theme === 'dark'}
          onChange={(e) => {
            setTheme(e.target.checked ? 'dark' : 'light')
          }}
        />
        Use dark mode
      </label>
    </ThemeContext.Provider>
  )
}

function Form({ children }) {
  return (
    <Panel title="Welcome">
      <Button>Sign up</Button>
      <Button>Log in</Button>
    </Panel>
  );
}

function Panel({ title, children }) {
  const theme = useContext(ThemeContext);
  const className = 'panel-' + theme;
  return (
    <section className={className}>
      <h1>{title}</h1>
      {children}
    </section>
  )
}

function Button({ children }) {
  const theme = useContext(ThemeContext);
  const className = 'button-' + theme;
  return (
    <button className={className}>
      {children}
    </button>
  );
}

value="dark"๋Š” "dark" ๋ฌธ์ž์—ด์„ ์ „๋‹ฌํ•˜์ง€๋งŒ, value={theme}๋Š” JSX ์ค‘๊ด„ํ˜ธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ JavaScript theme ๋ณ€์ˆ˜ ๊ฐ’์„ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ์ค‘๊ด„ํ˜ธ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฌธ์ž์—ด์ด ์•„๋‹Œ context ๊ฐ’๋„ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


fallback ๊ธฐ๋ณธ๊ฐ’ ์ง€์ •

React๊ฐ€ ๋ถ€๋ชจ ํŠธ๋ฆฌ์—์„œ ํŠน์ • context providers๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ, useContext()๊ฐ€ ๋ฐ˜ํ™˜ํ•˜๋Š” context ๊ฐ’์€ ํ•ด๋‹น context๋ฅผ ์ƒ์„ฑํ•  ๋•Œ์ง€์ •ํ•œ ๊ธฐ๋ณธ๊ฐ’๊ณผ ๋™์ผํ•ฉ๋‹ˆ๋‹ค.

const ThemeContext = createContext(null);

๊ธฐ๋ณธ๊ฐ’์€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. context๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋ ค๋ฉด ์œ„์—์„œ ์„ค๋ช…ํ•œ ๋Œ€๋กœ ์ƒํƒœ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜์„ธ์š”.

์˜ˆ๋ฅผ ๋“ค์–ด null ๋Œ€์‹ ์— ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋” ์˜๋ฏธ ์žˆ๋Š” ๊ฐ’์ด ์žˆ๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค.

const ThemeContext = createContext('light');

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์‹ค์ˆ˜๋กœ ํ•ด๋‹น provider ์—†์ด ์ผ๋ถ€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ•ด๋„ ๊นจ์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ์—์„œ ๋งŽ์€ provider๋ฅผ ์„ค์ •ํ•˜์ง€ ์•Š๊ณ ๋„ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ์—์„œ ์ž˜ ์ž‘๋™ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค.

์•„๋ž˜ ์˜ˆ์ œ์—์„œ โ€œToggle themeโ€ ๋ฒ„ํŠผ์€ ํ…Œ๋งˆ context provider์˜ ์™ธ๋ถ€ ์— ์žˆ๊ณ  ๊ธฐ๋ณธ ์ปจํ…์ŠคํŠธ ํ…Œ๋งˆ ๊ฐ’์ด 'light'์ด๊ธฐ ๋•Œ๋ฌธ์— ํ•ญ์ƒ ๋ฐ๊ฒŒ ํ‘œ์‹œ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธ ํ…Œ๋งˆ๋ฅผ 'dark'๋กœ ๋ณ€๊ฒฝํ•ด ๋ณด์„ธ์š”.

import { createContext, useContext, useState } from 'react';

const ThemeContext = createContext('light');

export default function MyApp() {
  const [theme, setTheme] = useState('light');
  return (
    <>
      <ThemeContext.Provider value={theme}>
        <Form />
      </ThemeContext.Provider>
      <Button onClick={() => {
        setTheme(theme === 'dark' ? 'light' : 'dark');
      }}>
        Toggle theme
      </Button>
    </>
  )
}

function Form({ children }) {
  return (
    <Panel title="Welcome">
      <Button>Sign up</Button>
      <Button>Log in</Button>
    </Panel>
  );
}

function Panel({ title, children }) {
  const theme = useContext(ThemeContext);
  const className = 'panel-' + theme;
  return (
    <section className={className}>
      <h1>{title}</h1>
      {children}
    </section>
  )
}

function Button({ children, onClick }) {
  const theme = useContext(ThemeContext);
  const className = 'button-' + theme;
  return (
    <button className={className} onClick={onClick}>
      {children}
    </button>
  );
}


ํŠธ๋ฆฌ์˜ ์ผ๋ถ€ context ์˜ค๋ฒ„๋ผ์ด๋“œ ํ•˜๊ธฐ

ํŠธ๋ฆฌ์˜ ์ผ๋ถ€๋ถ„์„ ๋‹ค๋ฅธ ๊ฐ’์˜ provider๋กœ ๊ฐ์‹ธ์„œ ํ•ด๋‹น ๋ถ€๋ถ„์— ๋Œ€ํ•œ context๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋“œ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

<ThemeContext.Provider value="dark">
...
<ThemeContext.Provider value="light">
<Footer />
</ThemeContext.Provider>
...
</ThemeContext.Provider>

ํ•„์š”ํ•œ ๋งŒํผ provider๋ฅผ ์ค‘์ฒฉํ•˜๊ณ  ์˜ค๋ฒ„๋ผ์ด๋“œ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Examples of overriding context

์˜ˆ์ œ 1 of 2:
theme ์˜ค๋ฒ„๋ผ์ด๋“œ

์—ฌ๊ธฐ์„œ Footer ๋‚ด๋ถ€์˜ ๋ฒ„ํŠผ์€ ์™ธ๋ถ€์˜ ๋ฒ„ํŠผ("dark")๊ณผ ๋‹ค๋ฅธ context ๊ฐ’("light")์„ ๋ฐ›์Šต๋‹ˆ๋‹ค.

import { createContext, useContext } from 'react';

const ThemeContext = createContext(null);

export default function MyApp() {
  return (
    <ThemeContext.Provider value="dark">
      <Form />
    </ThemeContext.Provider>
  )
}

function Form() {
  return (
    <Panel title="Welcome">
      <Button>Sign up</Button>
      <Button>Log in</Button>
      <ThemeContext.Provider value="light">
        <Footer />
      </ThemeContext.Provider>
    </Panel>
  );
}

function Footer() {
  return (
    <footer>
      <Button>Settings</Button>
    </footer>
  );
}

function Panel({ title, children }) {
  const theme = useContext(ThemeContext);
  const className = 'panel-' + theme;
  return (
    <section className={className}>
      {title && <h1>{title}</h1>}
      {children}
    </section>
  )
}

function Button({ children }) {
  const theme = useContext(ThemeContext);
  const className = 'button-' + theme;
  return (
    <button className={className}>
      {children}
    </button>
  );
}


๊ฐ์ฒด์™€ ํ•จ์ˆ˜๋ฅผ ์ „๋‹ฌํ•  ๋•Œ ๋ฆฌ๋ Œ๋”๋ง ์ตœ์ ํ™”ํ•˜๊ธฐ

context๋ฅผ ํ†ตํ•ด ๊ฐ์ฒด์™€ ํ•จ์ˆ˜๋ฅผ ํฌํ•จํ•œ ๋ชจ๋“  ๊ฐ’์„ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

function MyApp() {
const [currentUser, setCurrentUser] = useState(null);

function login(response) {
storeCredentials(response.credentials);
setCurrentUser(response.user);
}

return (
<AuthContext.Provider value={{ currentUser, login }}>
<Page />
</AuthContext.Provider>
);
}

์—ฌ๊ธฐ์„œ context value์€ ๋‘ ๊ฐœ์˜ ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ€์ง„ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ฐ์ฒด์ด๋ฉฐ, ๊ทธ ์ค‘ ํ•˜๋‚˜๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. MyApp์ด ๋‹ค์‹œ ๋ Œ๋”๋งํ•  ๋•Œ๋งˆ๋‹ค(์˜ˆ๋ฅผ ๋“ค์–ด ๊ฒฝ๋กœ ์—…๋ฐ์ดํŠธ ์‹œ) ๋‹ค๋ฅธ ํ•จ์ˆ˜๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ๋‹ค๋ฅธ ๊ฐ์ฒด๊ฐ€ ๋  ๊ฒƒ์ด๋ฏ€๋กœ React๋Š” useContext(AuthContext)๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ํŠธ๋ฆฌ ๊นŠ์ˆ™ํ•œ ๊ณณ์— ์žˆ๋Š” ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ๋„ ๋‹ค์‹œ ๋ Œ๋”๋งํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ž‘์€ ์•ฑ์—์„œ๋Š” ๋ฌธ์ œ๊ฐ€ ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ currentUser์™€ ๊ฐ™์€ ๊ธฐ๋ณธ์ ์ธ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์•˜๋‹ค๋ฉด ๋‹ค์‹œ ๋ Œ๋”๋งํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. React๊ฐ€ ์ด ์‚ฌ์‹ค์„ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก login ํ•จ์ˆ˜๋ฅผ useCallback์œผ๋กœ ๊ฐ์‹ธ๊ณ  ๊ฐ์ฒด ์ƒ์„ฑ์„ useMemo๋กœ ๊ฐ์‹ธ๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ์„ฑ๋Šฅ ์ตœ์ ํ™”์ž…๋‹ˆ๋‹ค.

import { useCallback, useMemo } from 'react';

function MyApp() {
const [currentUser, setCurrentUser] = useState(null);

const login = useCallback((response) => {
storeCredentials(response.credentials);
setCurrentUser(response.user);
}, []);

const contextValue = useMemo(() => ({
currentUser,
login
}), [currentUser, login]);

return (
<AuthContext.Provider value={contextValue}>
<Page />
</AuthContext.Provider>
);
}

์ด ๋ณ€๊ฒฝ์œผ๋กœ ์ธํ•ด MyApp์ด ๋‹ค์‹œ ๋ Œ๋”๋งํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ์—๋„ currentUser๊ฐ€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๋Š” ํ•œ useContext(AuthContext)๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ๋Š” ๋‹ค์‹œ ๋ Œ๋”๋งํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

useMemo ์™€ useCallback ์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์•Œ์•„๋ณด์„ธ์š”.


๋ฌธ์ œ ํ•ด๊ฒฐ

์ปดํฌ๋„ŒํŠธ์— provider ๊ฐ’์ด ๋ณด์ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ด๋Ÿฐ ์ผ์ด ๋ฐœ์ƒํ•˜๋Š” ๋ช‡ ๊ฐ€์ง€ ์ด์œ ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

  1. useContext()๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ์™€ ๋™์ผํ•œ ์ปดํฌ๋„ŒํŠธ(๋˜๋Š” ๊ทธ ์•„๋ž˜)์—์„œ <SomeContext.Provider>๋ฅผ ๋ Œ๋”๋งํ•˜๋Š” ๊ฒฝ์šฐ. <SomeContext.Provider>๋ฅผ useContext()๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ์˜ ์œ„์™€ ๋ฐ”๊นฅ์œผ๋กœ ์ด๋™ํ•˜์„ธ์š”.
  2. ์ปดํฌ๋„ŒํŠธ๋ฅผ <SomeContext.Provider>๋กœ ๊ฐ์‹ธ๋Š” ๊ฒƒ์„ ์žŠ์—ˆ๊ฑฐ๋‚˜ ์ƒ๊ฐํ–ˆ๋˜ ๊ฒƒ๊ณผ ๋‹ค๋ฅธ ํŠธ๋ฆฌ์˜ ๋‹ค๋ฅธ ๋ถ€๋ถ„์— ๋ฐฐ์น˜ํ–ˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. React ๊ฐœ๋ฐœ์ž ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ณ„์ธต ๊ตฌ์กฐ๊ฐ€ ์˜ฌ๋ฐ”๋ฅธ์ง€ ํ™•์ธํ•˜์„ธ์š”.
  3. ์ œ๊ณตํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ณด๋Š” someContext์™€ ์ฝ๋Š” ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ณด๋Š” someContext๊ฐ€ ์„œ๋กœ ๋‹ค๋ฅธ ๋‘ ๊ฐœ์˜ ๊ฐ์ฒด๊ฐ€ ๋˜๋Š” ๋นŒ๋“œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์‹ฌ๋ณผ๋ฆญ ๋งํฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ์ด๋Ÿฐ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ™•์ธํ•˜๋ ค๋ฉด window.SomeContext1์™€ window.SomeContext2์„ ์ „์—ญ์— ํ• ๋‹นํ•˜๊ณ  ์ฝ˜์†”์—์„œ window.SomeContext1 === window.SomeContext2์ธ์ง€ ํ™•์ธํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ๋™์ผํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ๋นŒ๋“œ ๋„๊ตฌ ์ˆ˜์ค€์—์„œ ํ•ด๋‹น ๋ฌธ์ œ๋ฅผ ์ˆ˜์ •ํ•˜์„ธ์š”.

๊ธฐ๋ณธ๊ฐ’์ด ๋‹ค๋ฅธ๋ฐ๋„ context๊ฐ€ undefined์ด ๋ฉ๋‹ˆ๋‹ค.

ํŠธ๋ฆฌ์— value๊ฐ€ ์—†๋Š” provider๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

// ๐Ÿšฉ Doesn't work: no value prop
<ThemeContext.Provider>
<Button />
</ThemeContext.Provider>

value๋ฅผ ์ง€์ •ํ•˜๋Š” ๊ฒƒ์„ ์žŠ์–ด๋ฒ„๋ฆฐ ๊ฒฝ์šฐ, value={undefined}๋ฅผ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์‹ค์ˆ˜๋กœ ๋‹ค๋ฅธ prop์˜ ์ด๋ฆ„์„ ์‹ค์ˆ˜๋กœ ์‚ฌ์šฉํ–ˆ์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

// ๐Ÿšฉ Doesn't work: prop should be called "value"
<ThemeContext.Provider theme={theme}>
<Button />
</ThemeContext.Provider>

๋‘ ๊ฐ€์ง€ ๊ฒฝ์šฐ ๋ชจ๋‘ ์ฝ˜์†”์— React์—์„œ ๊ฒฝ๊ณ ๊ฐ€ ํ‘œ์‹œ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋ฅผ ์ˆ˜์ •ํ•˜๋ ค๋ฉด prop value๋ฅผ ํ˜ธ์ถœํ•˜์„ธ์š”.

// โœ… Passing the value prop
<ThemeContext.Provider value={theme}>
<Button />
</ThemeContext.Provider>

createContext(defaultValue) ํ˜ธ์ถœ์˜ ๊ธฐ๋ณธ๊ฐ’์€ ์œ„์— ์ผ์น˜ํ•˜๋Š” provider๊ฐ€ ์ „ํ˜€ ์—†๋Š” ๊ฒฝ์šฐ์—๋งŒ ์‚ฌ์šฉ๋œ๋‹ค๋Š” ์ ์— ์œ ์˜ํ•˜์„ธ์š”. ๋ถ€๋ชจ ํŠธ๋ฆฌ ์–ด๋”˜๊ฐ€์— <SomeContext.Provider value={undefined}> ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ, useContext(SomeContext)๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ๋Š” undefined๋ฅผ context ๊ฐ’์œผ๋กœ ๋ฐ›์Šต๋‹ˆ๋‹ค.