{"id":779,"date":"2026-05-18T23:01:36","date_gmt":"2026-05-18T15:01:36","guid":{"rendered":"https:\/\/junai.ai\/blog\/react-context-13\/"},"modified":"2026-05-19T20:26:20","modified_gmt":"2026-05-19T12:26:20","slug":"react-context-13","status":"publish","type":"post","link":"https:\/\/junai.ai\/blog\/react-context-13\/","title":{"rendered":"React Context API \u2014 \uc804\uc5ed \uc0c1\ud0dc (Ch.13)"},"content":{"rendered":"\n<!-- WordPress REST API \ubc1c\ud589\uc6a9 HTML (\uc790\ub3d9 \uc0dd\uc131) -->\n<!-- WP-FEATURED-MEDIA-ID: 753 -->\n<div style=\"max-width:800px;margin:0 auto;\">\n<style>\n:root {--color-primary:#0891b2;--color-accent:#06b6d4;--color-bg:#f8fafc;--color-bg-card:#fff;--color-text:#0f172a;--color-text-muted:#64748b;--hero-start:#0f172a;--hero-end:#0891b2;}\n*{box-sizing:border-box;}\n.container{max-width:760px;margin:0 auto;padding:0 24px 80px;}\n.hero{background:linear-gradient(135deg,var(--hero-start) 0%,var(--hero-end) 100%);color:#fff;padding:80px 24px 60px;text-align:center;}\n.hero .eyebrow{display:inline-block;font-size:14px;color:#67e8f9;font-weight:700;letter-spacing:0.1em;text-transform:uppercase;margin-bottom:14px;}\n.hero h1{font-size:36px;margin:0 0 16px;line-height:1.3;font-weight:800;}\n.hero p{color:#cffafe;font-size:18px;max-width:640px;margin:0 auto;line-height:1.6;}\n.hero img{width:100%;max-width:640px;height:auto;margin:32px auto 0;border-radius:10px;display:block;}\narticle{padding-top:48px;}\narticle h2{font-size:26px;margin:56px 0 20px;padding-left:14px;border-left:5px solid var(--color-accent);line-height:1.4;}\narticle h3{font-size:19px;margin:32px 0 12px;color:var(--color-primary);}\narticle p{margin:16px 0;}\narticle strong{color:var(--color-primary);font-weight:700;}\narticle code{background:#ecfeff;padding:2px 8px;border-radius:4px;font-family:'SF Mono',Menlo,Consolas,monospace;font-size:14px;color:#0e7490;}\n.databox{background:#ecfeff;border-left:4px solid var(--color-accent);padding:16px 20px;margin:24px 0;border-radius:0 8px 8px 0;font-size:15.5px;}\n.databox strong{color:var(--color-primary);}\n.warnbox{background:linear-gradient(135deg,#fef3c7 0%,#fde68a 100%);padding:16px 20px;margin:24px 0;border-radius:8px;font-size:15.5px;}\n.code-block{background:#0f172a;color:#e2e8f0;padding:16px 20px;border-radius:8px;font-family:'SF Mono',Menlo,Consolas,monospace;font-size:14px;line-height:1.6;margin:20px 0;overflow-x:auto;white-space:pre;}\n.cta{background:linear-gradient(135deg,#0891b2 0%,#06b6d4 100%);color:#fff;padding:28px 24px;border-radius:12px;margin:48px 0 0;text-align:center;}\n.cta h3{color:#fff;margin:0 0 8px;font-size:20px;}\n.cta p{color:#cffafe;margin:0;font-size:15.5px;}\n.footer-nav{margin-top:32px;padding-top:20px;border-top:1px solid #e2e8f0;font-size:14px;color:var(--color-text-muted);}\n.footer-nav a{color:var(--color-primary);text-decoration:none;}\n@media (max-width:480px){.hero h1{font-size:26px;}.hero p{font-size:16px;}article h2{font-size:21px;}article h3{font-size:17px;}body{font-size:16px;}}\n<\/style>\n<section class=\"hero\">\n  <span class=\"eyebrow\">React \uad50\uc7ac \u00b7 \uc911\uae09 13\ud3b8<\/span>\n  <h1>React Context API \u2014 \uc804\uc5ed \uc0c1\ud0dc<\/h1>\n  <p>\uac19\uc740 \uac12\uc744 props \ub85c 5\ub2e8\uacc4 \ub0b4\ub824\ubcf4\ub0b4\ub294 \uc9c0\uc625 \ub05d\ub0b4\uae30. Context + useContext \ud55c \uc30d.<\/p>\n  <img decoding=\"async\" src=\"https:\/\/junai.ai\/blog\/wp-content\/uploads\/2026\/05\/hero-5-36.jpg\" alt=\"\uc911\uc559 \ub370\uc774\ud130 \uad6c\uc2ac\uc5d0\uc11c \uae4a\uc774 \uc911\ucca9\ub41c UI \uce74\ub4dc\ub4e4\uc5d0 \uac12\uc774 \ud758\ub7ec\ub0b4\ub9ac\ub294 \uc77c\ub7ec\uc2a4\ud2b8 \u2014 Context \uacf5\uc720 \uc0c1\ud0dc \ucee8\uc149\">\n<\/section>\n\n<div class=\"container\">\n<article>\n\n<p>App \ucef4\ud3ec\ub10c\ud2b8\uac00 \uc0ac\uc6a9\uc790 \uc815\ubcf4(<code>user<\/code>)\ub97c \uac00\uc9c0\uace0 \uc788\uace0, \ud654\uba74 \uae4a\uc219\ud55c <code>UserMenu<\/code> \ucef4\ud3ec\ub10c\ud2b8\uac00 \uadf8\uac78 \ud544\uc694\ub85c \ud55c\ub2e4. \uc0ac\uc774\uc5d0 <code>Layout<\/code>\u00b7<code>Header<\/code>\u00b7<code>Nav<\/code> \uac00 \uc788\ub294\ub370, \uc14b \ub2e4 user \ub97c \uc548 \uc4f0\uc9c0\ub9cc \ub2e8\uc9c0 \ud1b5\uacfc\uc2dc\ud0a4\uae30 \uc704\ud574 prop \uc73c\ub85c \ubc1b\uc544 \ub2e4\uc2dc \ub0b4\ub824\ubcf4\ub0b8\ub2e4. \uc774\uac8c <strong>prop drilling<\/strong> \u2014 \uadf8\ub9ac\uace0 React Context \uac00 \ud478\ub294 \ubb38\uc81c.<\/p>\n\n<p>\uc774\ubc88 13\ud3b8\uc740 Context \uc758 3 \ubd80\ud488(<code>createContext<\/code>\u00b7<code>Provider<\/code>\u00b7<code>useContext<\/code>) + \uc5b8\uc81c \uc368\uc57c \ud558\uace0 \uc5b8\uc81c \uc4f0\uba74 \uc548 \ub418\ub294\uc9c0 + \uc131\ub2a5 \ud568\uc815 + \ud68c\uc0ac stack \uc5d0 \ub450\uae30 \uc88b\uc740 \ub300\uc548 (Zustand) \uae4c\uc9c0.<\/p>\n\n<h2>1. 3 \ubd80\ud488 \u2014 createContext \u00b7 Provider \u00b7 useContext<\/h2>\n\n<div class=\"code-block\">\/\/ 1. Context \uc0dd\uc131\nimport { createContext, useContext } from &#8216;react&#8217;;\n\nconst ThemeContext = createContext&lt;&#8216;light&#8217; | &#8216;dark&#8217;&gt;(&#8216;light&#8217;);\n\n\/\/ 2. Provider \u2014 \uac12 \uacf5\uae09\nfunction App() {\n  const [theme, setTheme] = useState(&#8216;light&#8217;);\n  return (\n    &lt;ThemeContext.Provider value={theme}&gt;\n      &lt;Layout \/&gt;\n    &lt;\/ThemeContext.Provider&gt;\n  );\n}\n\n\/\/ 3. useContext \u2014 \uc5b4\ub290 \uae4a\uc774\uc5d0\uc11c\ub4e0 \uc77d\uae30\nfunction DeepButton() {\n  const theme = useContext(ThemeContext);\n  return &lt;button className={theme}&gt;&#8230;&lt;\/button&gt;;\n}<\/div>\n\n<p><code>Layout<\/code>\u00b7<code>Header<\/code>\u00b7\uc911\uac04 \ucef4\ud3ec\ub10c\ud2b8\ub4e4\uc774 theme \uc744 prop \uc73c\ub85c \ubc1b\uc9c0 \uc54a\ub294\ub2e4. <code>DeepButton<\/code> \uc774 <code>useContext<\/code> \ud55c \uc904\ub85c \uc9c1\uc811 \uc811\uadfc. prop drilling 5\ub2e8\uacc4\uac00 0\ub2e8\uacc4.<\/p>\n\n<div class=\"databox\">\n<strong>\ud575\uc2ec \uc774\ud574<\/strong> \u2014 Context \uac00 \ub9c8\ubc95\uc740 \uc544\ub2c8\ub2e4. React \uac00 \ucef4\ud3ec\ub10c\ud2b8 \ud2b8\ub9ac\ub97c \uc62c\ub77c\uac00\uba70 \uac00\uc7a5 \uac00\uae4c\uc6b4 Provider \ub97c \ucc3e\uc544 \uadf8 value \ub97c \ubc18\ud658\ud560 \ubfd0. Provider \uac00 \uc5c6\uc73c\uba74 createContext \uc758 \uae30\ubcf8\uac12 \uc0ac\uc6a9. Provider \uac00 \uc5ec\ub7ec \uac1c\uba74 \uac00\uc7a5 \uac00\uae4c\uc6b4 \uac83 \uc6b0\uc120.\n<\/div>\n\n<h2>2. \uc9c4\uc9dc \ud328\ud134 \u2014 value + updater \uac19\uc774 \uacf5\uae09<\/h2>\n\n<p>\uc704 \uc608\uc81c\ub294 theme \ub9cc \uacf5\uae09. \uc2e4\uc804\uc5d0\uc120 <strong>\uac12 + \ubcc0\uacbd \ud568\uc218\ub97c \uac1d\uccb4\ub85c \ubb36\uc5b4 \uacf5\uae09<\/strong>:<\/p>\n\n<div class=\"code-block\">type ThemeContextType = {\n  theme: &#8216;light&#8217; | &#8216;dark&#8217;;\n  toggle: () =&gt; void;\n};\n\nconst ThemeContext = createContext&lt;ThemeContextType | null&gt;(null);\n\nexport function ThemeProvider({ children }) {\n  const [theme, setTheme] = useState&lt;&#8216;light&#8217; | &#8216;dark&#8217;&gt;(&#8216;light&#8217;);\n  const toggle = () =&gt; setTheme(t =&gt; t === &#8216;light&#8217; ? &#8216;dark&#8217; : &#8216;light&#8217;);\n  return (\n    &lt;ThemeContext.Provider value={{ theme, toggle }}&gt;\n      {children}\n    &lt;\/ThemeContext.Provider&gt;\n  );\n}\n\n\/\/ \ud3b8\uc758 Hook\nexport function useTheme() {\n  const ctx = useContext(ThemeContext);\n  if (!ctx) throw new Error(&#8216;useTheme must be inside ThemeProvider&#8217;);\n  return ctx;\n}\n\n\/\/ \uc0ac\uc6a9\nfunction ThemeToggle() {\n  const { theme, toggle } = useTheme();\n  return &lt;button onClick={toggle}&gt;{theme}&lt;\/button&gt;;\n}<\/div>\n\n<p>\uc774 \ud328\ud134 3\uac00\uc9c0 \uc7a5\uc810 \u2014 \u2460 \uac19\uc740 \ucee8\ud14d\uc2a4\ud2b8\uc5d0\uc11c \uac12\u00b7\ubcc0\uacbd \ud568\uc218\ub97c \ud55c \ubc88\uc5d0. \u2461 \ucee4\uc2a4\ud140 Hook (<code>useTheme<\/code>) \uc774 Provider \uc5c6\uc774 \uc0ac\uc6a9\ud558\ub294 \uc2e4\uc218\ub97c \ucef4\ud30c\uc77c\/\ub7f0\ud0c0\uc784 \ub458 \ub2e4\uc5d0\uc11c \uc7a1\uc74c. \u2462 12\ud3b8 \ucee4\uc2a4\ud140 Hook \uc640 \uc790\uc5f0\uc2a4\ub7ec\uc6b4 \uacb0\ud569.<\/p>\n\n<h2>3. \uc131\ub2a5 \ud568\uc815 \u2014 Provider value \uac00 \ub9e4 \ub80c\ub354\ub9c8\ub2e4 \uc0c8 \uac1d\uccb4<\/h2>\n\n<p>\uc704 \ucf54\ub4dc\uc758 <code>value={{ theme, toggle }}<\/code> \uac00 \uc0ac\uace0 \uc9c0\uc810. \ubd80\ubaa8 \ucef4\ud3ec\ub10c\ud2b8\uac00 \ub2e4\ub978 \uc774\uc720\ub85c \uc7ac\ub80c\ub354\ub418\uba74 <strong>\ub9e4\ubc88 \uc0c8 \uac1d\uccb4<\/strong> \uac00 \ub9cc\ub4e4\uc5b4\uc9c4\ub2e4 \u2192 Context \uad6c\ub3c5\uc790 \uc804\ubd80 \uc7ac\ub80c\ub354. theme \uc774 \uc548 \ubc14\ub00c\uc5b4\ub3c4.<\/p>\n\n<p>\ud574\uacb0 \u2014 <strong>useMemo<\/strong> \ub85c \uac1d\uccb4 \uba54\ubaa8\uc774\uc988 (16\ud3b8 \uc790\uc138\ud788):<\/p>\n\n<div class=\"code-block\">const value = useMemo(() =&gt; ({ theme, toggle }), [theme]);\nreturn &lt;ThemeContext.Provider value={value}&gt;{children}&lt;\/ThemeContext.Provider&gt;;<\/div>\n\n<p>\ub610\ub294 \u2014 <strong>state \uc640 dispatch \ub97c \ub2e4\ub978 Context \ub450 \uac1c<\/strong>\ub85c \ubd84\ub9ac. \uac12\ub9cc \ud544\uc694\ud55c \ucef4\ud3ec\ub10c\ud2b8\ub294 state Context, \ubcc0\uacbd\ub9cc \ud544\uc694\ud55c \ucef4\ud3ec\ub10c\ud2b8\ub294 dispatch Context \uad6c\ub3c5. dispatch \ub294 \uc548 \ubc14\ub00c\ub2c8 \uc7ac\ub80c\ub354 0. Redux \uac00 \uc61b\ub0a0\ubd80\ud130 \uc4f0\ub358 \ud328\ud134.<\/p>\n\n<h2>4. Context \uc758 \ud55c\uacc4 \u2014 Zustand \uac00 \ub2f5\uc77c \ub54c<\/h2>\n\n<p>Context \uac00 \uc801\ud569\ud55c \uacbd\uc6b0 \u2014 <strong>\uc798 \uc548 \ubc14\ub00c\ub294 \uc804\uc5ed \uac12<\/strong> (theme\u00b7locale\u00b7\ub85c\uadf8\uc778 \uc0ac\uc6a9\uc790\u00b7\uc778\uc99d \ud1a0\ud070). \uc790\uc8fc \ubc14\ub00c\ub294 state (\uc7a5\ubc14\uad6c\ub2c8 \ud56d\ubaa9 \uc218\u00b7\uc2e4\uc2dc\uac04 \uc54c\ub9bc \uce74\uc6b4\ud2b8) \uc5d0 Context \ub97c \uc4f0\uba74 \uc704 \uc131\ub2a5 \ud568\uc815\uc774 \uc77c\uc0c1.<\/p>\n\n<p>\uadf8\ub7f0 \uacbd\uc6b0 \u2014 <strong>Zustand<\/strong> \u00b7 Jotai \u00b7 TanStack Store \uac19\uc740 \uc678\ubd80 \uc0c1\ud0dc \uad00\ub9ac. \ud68c\uc0ac stack \uc5d0 Zustand \uac00 \uc790\uc8fc \ub4e4\uc5b4\uac00\ub294 \uc774\uc720\ub2e4.<\/p>\n\n<div class=\"code-block\">\/\/ Zustand \uc608\uc2dc \u2014 Context \ubcf4\ub2e4 \uac04\ub2e8\nimport { create } from &#8216;zustand&#8217;;\n\nconst useCartStore = create((set) =&gt; ({\n  items: [],\n  add: (item) =&gt; set((s) =&gt; ({ items: [&#8230;s.items, item] })),\n}));\n\nfunction CartCount() {\n  const count = useCartStore((s) =&gt; s.items.length);  \/\/ \u2190 selector\n  return &lt;span&gt;{count}&lt;\/span&gt;;\n}<\/div>\n\n<p>\ud575\uc2ec \u2014 Zustand \ub294 <strong>selector<\/strong> \ub85c &#8220;\uc774 \ucef4\ud3ec\ub10c\ud2b8\ub294 items.length \ub9cc \ubcf8\ub2e4&#8221; \uba85\uc2dc. items \ubc30\uc5f4 \uc790\uccb4\uac00 \ubc14\ub00c\uc5b4\ub3c4 length \uac00 \uac19\uc73c\uba74 \uc7ac\ub80c\ub354 0. Context \uac00 \ubabb \ud558\ub294 \uc77c.<\/p>\n\n<div class=\"warnbox\">\n<strong>\uc2e4\uc804 \uac00\uc774\ub4dc<\/strong> \u2014 \uc791\uc740 \uc571 + \uc798 \uc548 \ubc14\ub00c\ub294 \uac12 \u2192 Context. \ud070 \uc571 + \uc790\uc8fc \ubc14\ub00c\ub294 \uac12 \u2192 Zustand (\ub610\ub294 Redux Toolkit). \ub458 \ub2e4 \uc4f0\ub294 \uac8c \uc815\uc0c1 \u2014 \uc815\ub2f5\uc740 \ub458 \uc911 \ud558\ub098\uac00 \uc544\ub2d8.\n<\/div>\n\n<p>13\ud3b8\uc73c\ub85c \ucef4\ud3ec\ub10c\ud2b8 \uac04 \ub370\uc774\ud130 \uacf5\uc720 \ud328\ud134\uc774 \uc644\uc131. 14\ud3b8 useReducer \ub294 \uadf8 \uc548\uc5d0\uc11c \ub2e4\ub8e8\ub294 state \uac00 \ubcf5\uc7a1\ud574\uc9c8 \ub54c useState \uc758 \uc9c4\ud654\ud615. Context + useReducer \uc870\ud569\uc774 Redux \uc9c1\uc804\uae4c\uc9c0 \ucee4\ubc84\ud55c\ub2e4.<\/p>\n\n<div class=\"cta\">\n<h3>\ub2e4\uc74c \uae00<\/h3>\n<p>React \uad50\uc7ac 14\ud3b8 \u2014 useReducer. \ubcf5\uc7a1\ud55c state + action + reducer \ud328\ud134, useState \uc640 \uc5b8\uc81c \uac08\uc544\ud0c8\uc9c0 \uae30\uc900.<\/p>\n<\/div>\n\n<div class=\"footer-nav\">\nReact \uad50\uc7ac \uc2dc\ub9ac\uc988 \u00b7\n<a href=\"https:\/\/junai.ai\/blog\/react-useeffect-11\/\">11\ud3b8 useEffect<\/a> \u00b7\n<a href=\"https:\/\/junai.ai\/blog\/react-custom-hooks-12\/\">12\ud3b8 Custom Hook<\/a> \u00b7\n<strong>13\ud3b8 Context<\/strong>\n<\/div>\n\n<\/article>\n<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>React Context \u2014 prop drilling \ud0c8\ucd9c, createContext + useContext, \uc131\ub2a5 \ud568\uc815, Zustand \ub300\uc548. \uad50\uc7ac 13\ud3b8.<\/p>\n","protected":false},"author":1,"featured_media":753,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[22],"tags":[],"class_list":["post-779","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-react"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/junai.ai\/blog\/wp-json\/wp\/v2\/posts\/779","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/junai.ai\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/junai.ai\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/junai.ai\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/junai.ai\/blog\/wp-json\/wp\/v2\/comments?post=779"}],"version-history":[{"count":1,"href":"https:\/\/junai.ai\/blog\/wp-json\/wp\/v2\/posts\/779\/revisions"}],"predecessor-version":[{"id":801,"href":"https:\/\/junai.ai\/blog\/wp-json\/wp\/v2\/posts\/779\/revisions\/801"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/junai.ai\/blog\/wp-json\/wp\/v2\/media\/753"}],"wp:attachment":[{"href":"https:\/\/junai.ai\/blog\/wp-json\/wp\/v2\/media?parent=779"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/junai.ai\/blog\/wp-json\/wp\/v2\/categories?post=779"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/junai.ai\/blog\/wp-json\/wp\/v2\/tags?post=779"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}