{"id":772,"date":"2026-05-18T23:01:20","date_gmt":"2026-05-18T15:01:20","guid":{"rendered":"https:\/\/junai.ai\/blog\/react-useeffect-11\/"},"modified":"2026-05-19T20:26:18","modified_gmt":"2026-05-19T12:26:18","slug":"react-useeffect-11","status":"publish","type":"post","link":"https:\/\/junai.ai\/blog\/react-useeffect-11\/","title":{"rendered":"React useEffect \uc815\ubcf5 (Ch.11)"},"content":{"rendered":"\n<!-- WordPress REST API \ubc1c\ud589\uc6a9 HTML (\uc790\ub3d9 \uc0dd\uc131) -->\n<!-- WP-FEATURED-MEDIA-ID: 747 -->\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 11\ud3b8<\/span>\n  <h1>React useEffect \u2014 side effect \u00b7 cleanup<\/h1>\n  <p>\uc678\ubd80 \uc138\uacc4\uc640 \ub3d9\uae30\ud654\ud558\ub294 Hook. \ub370\uc774\ud130 fetch\u00b7\uad6c\ub3c5\u00b7timer \u2014 \uadf8\ub9ac\uace0 \uac00\uc7a5 \ud754\ud55c \ubb34\ud55c \ub8e8\ud504 \ud568\uc815.<\/p>\n  <img decoding=\"async\" src=\"https:\/\/junai.ai\/blog\/wp-content\/uploads\/2026\/05\/hero-5-30.jpg\" alt=\"\ucef4\ud3ec\ub10c\ud2b8 \uce74\ub4dc \uc606 \ub3d9\uae30 \uc2dc\uacc4\uc640 \uc678\ubd80 \ub370\uc774\ud130 \ud30c\uc774\ud504 \uc77c\ub7ec\uc2a4\ud2b8 \u2014 useEffect \uc0ac\uc774\ub4dc \uc774\ud399\ud2b8 \ucee8\uc149\">\n<\/section>\n\n<div class=\"container\">\n<article>\n\n<p>\uc9c0\uae08\uae4c\uc9c0 \ub2e4\ub8ec \ucef4\ud3ec\ub10c\ud2b8\ub294 &#8220;props \uc640 state \ub9cc \ubcf4\uace0 JSX \uadf8\ub9ac\uae30&#8221; \ub9cc \ud588\ub2e4. \uc21c\uc218 \ud568\uc218. \uadf8\ub7f0\ub370 \uc2e4\uc804 \uc571\uc740 \uc678\ubd80 \uc138\uacc4\uc640 \ud1b5\uc2e0\ud574\uc57c \ud55c\ub2e4 \u2014 <strong>API \ud638\ucd9c, WebSocket \uad6c\ub3c5, timer \uc2dc\uc791, DOM \uc9c1\uc811 \uc870\uc791, \ub85c\uae45<\/strong>. \uc774\ub7f0 \uac78 React \ub294 <em>side effect<\/em> (\ubd80\uc791\uc6a9) \ub77c \ubd80\ub978\ub2e4.<\/p>\n\n<p>useEffect \ub294 side effect \ub97c \uc548\uc804\ud55c \uc2dc\uc810\uc5d0 \uc2e4\ud589\ud558\uae30 \uc704\ud55c Hook. \uc798\ubabb \uc4f0\uba74 \ubb34\ud55c \ub8e8\ud504, \uba54\ubaa8\ub9ac \ub204\uc218, \uc61b \ub370\uc774\ud130 \uc0ac\uc6a9 \ub4f1 \uc2e0\ub098\ub294 \uc0ac\uace0\uac00 \uc904\uc904\uc774. \uc774\ubc88 11\ud3b8\uc5d0\uc11c \ud55c \ubc88\uc5d0 \uc815\ub9ac.<\/p>\n\n<h2>1. \uc5b8\uc81c \uc2e4\ud589\ub418\ub098 \u2014 \ub80c\ub354 \uc9c1\ud6c4<\/h2>\n\n<p>useEffect \uccab \uc778\uc790\ub294 &#8220;\ub80c\ub354 \ud6c4 \uc2e4\ud589\ud560 \ud568\uc218&#8221;. \ub450 \ubc88\uc9f8 \uc778\uc790\ub294 &#8220;\uc5b8\uc81c \ub2e4\uc2dc \uc2e4\ud589\ud560\uc9c0&#8221; dependency array.<\/p>\n\n<div class=\"code-block\">import { useEffect, useState } from &#8216;react&#8217;;\n\nfunction UserProfile({ userId }) {\n  const [user, setUser] = useState(null);\n\n  useEffect(() =&gt; {\n    fetch(`\/api\/users\/${userId}`)\n      .then(r =&gt; r.json())\n      .then(setUser);\n  }, [userId]);   \/\/ userId \uac00 \ubc14\ub014 \ub54c\ub9c8\ub2e4 \ub2e4\uc2dc fetch\n\n  if (!user) return &lt;p&gt;\ub85c\ub529&#8230;&lt;\/p&gt;;\n  return &lt;h1&gt;{user.name}&lt;\/h1&gt;;\n}<\/div>\n\n<p>\ud750\ub984 \u2014 \ucef4\ud3ec\ub10c\ud2b8\uac00 \ucc98\uc74c \ub9c8\uc6b4\ud2b8 \u2192 \ud654\uba74\uc5d0 &#8220;\ub85c\ub529&#8230;&#8221; \uadf8\ub824\uc9d0 \u2192 \uadf8 \uc9c1\ud6c4 useEffect \uc2e4\ud589 \u2192 fetch \u2192 setUser \u2192 state \ubcc0\ud654 \u2192 \uc7ac\ub80c\ub354 \u2192 &#8220;user.name&#8221; \ud45c\uc2dc.<\/p>\n\n<h2>2. dependency array \u2014 3\uac00\uc9c0 \uacbd\uc6b0<\/h2>\n\n<p>\ub450 \ubc88\uc9f8 \uc778\uc790\uc5d0 \ubb34\uc5c7\uc744 \ub123\ub0d0\uc5d0 \ub530\ub77c \uc2e4\ud589 \ube48\ub3c4 \uacb0\uc815.<\/p>\n\n<div class=\"code-block\">\/\/ \ud328\ud134 1 \u2014 \ub9e4 \ub80c\ub354\ub9c8\ub2e4 \uc2e4\ud589 (\uac70\uc758 \uc548 \uc500, \ubb34\ud55c \ub8e8\ud504 \uc704\ud5d8)\nuseEffect(() =&gt; { &#8230; });\n\n\/\/ \ud328\ud134 2 \u2014 \ub9c8\uc6b4\ud2b8 \uc2dc 1\ubc88\ub9cc (\ucd08\uae30\ud654\u00b7\uad6c\ub3c5 \uc2dc\uc791)\nuseEffect(() =&gt; { &#8230; }, []);\n\n\/\/ \ud328\ud134 3 \u2014 \uc758\uc874 \uac12\uc774 \ubc14\ub014 \ub54c\ub9cc (\uac00\uc7a5 \ud754\ud568)\nuseEffect(() =&gt; { &#8230; }, [userId, isActive]);<\/div>\n\n<div class=\"databox\">\n<strong>\ud575\uc2ec \uaddc\uce59<\/strong> \u2014 effect \uc548\uc5d0\uc11c \uc0ac\uc6a9\ud558\ub294 \ubaa8\ub4e0 props\u00b7state \ub294 dependency \ubc30\uc5f4\uc5d0 \ud3ec\ud568\ud574\uc57c. ESLint rule (<code>react-hooks\/exhaustive-deps<\/code>) \uac00 \uc790\ub3d9 \uac80\uc0ac. \ube60\ub728\ub9ac\uba74 \uc61b \uac12(stale closure) \uc0ac\uc6a9 \ubc84\uadf8.\n<\/div>\n\n<h2>3. cleanup \u2014 return \ud568\uc218\uc758 \uc9c4\uc9dc \uc758\ubbf8<\/h2>\n\n<p>\uad6c\ub3c5\u00b7timer \ucc98\ub7fc \uc2dc\uc791\ud588\uc73c\uba74 \uba48\ucdb0\uc57c \ud558\ub294 \uc791\uc5c5\uc740 <strong>cleanup function<\/strong> \uc73c\ub85c. useEffect \ucf5c\ubc31\uc774 <em>\ub2e4\ub978 \ud568\uc218<\/em> \ub97c return \ud558\uba74 \uadf8\uac8c cleanup.<\/p>\n\n<div class=\"code-block\">function Clock() {\n  const [time, setTime] = useState(new Date());\n\n  useEffect(() =&gt; {\n    const id = setInterval(() =&gt; setTime(new Date()), 1000);\n    return () =&gt; clearInterval(id);  \/\/ \u2190 cleanup\n  }, []);\n\n  return &lt;p&gt;{time.toLocaleTimeString()}&lt;\/p&gt;;\n}<\/div>\n\n<p>cleanup \uc774 \ud638\ucd9c\ub418\ub294 \uc2dc\uc810 \u2014 \u2460 \ucef4\ud3ec\ub10c\ud2b8\uac00 \uc5b8\ub9c8\uc6b4\ud2b8\ub420 \ub54c, \u2461 dependency \uac00 \ubc14\ub00c\uc5b4 effect \uac00 \ub2e4\uc2dc \uc2e4\ud589\ub418\uae30 \uc9c1\uc804. \u2461\uac00 \ud575\uc2ec \u2014 \uc61b effect \uc758 \uad6c\ub3c5\uc744 \ub04a\uace0 \uc0c8 effect \uc758 \uad6c\ub3c5\uc744 \uc2dc\uc791.<\/p>\n\n<p>cleanup \uc548 \uc4f0\uba74 \u2014 Clock \ucef4\ud3ec\ub10c\ud2b8\uac00 \uc0ac\ub77c\uc838\ub3c4 setInterval \uc774 \uacc4\uc18d \ub3cc\uace0 setTime \ud638\ucd9c \uc2dc\ub3c4 \u2192 React \ucf58\uc194 &#8220;Can&#8217;t perform state update on unmounted component&#8221; \uacbd\uace0 + \uba54\ubaa8\ub9ac \ub204\uc218.<\/p>\n\n<h2>4. \ubb34\ud55c \ub8e8\ud504 \u2014 \uac00\uc7a5 \ud754\ud55c \ud568\uc815 3\uc885<\/h2>\n\n<p>\ubaa8\ub4e0 React \uac1c\ubc1c\uc790\uac00 \ud55c \ubc88\uc740 \uacaa\ub294\ub2e4. \ud328\ud134 3\uac1c \ubc15\uc81c.<\/p>\n\n<h3>\ud568\uc815 1 \u2014 dependency \ube60\ub728\ub9bc + state \ubcc0\uacbd<\/h3>\n\n<div class=\"code-block\">useEffect(() =&gt; {\n  setCount(count + 1);  \/\/ state \ubcc0\uacbd \u2192 \uc7ac\ub80c\ub354 \u2192 effect \ub2e4\uc2dc \u2192 \ubb34\ud55c\n});  \/\/ dependency \uc5c6\uc74c!<\/div>\n\n<h3>\ud568\uc815 2 \u2014 \uac1d\uccb4\/\ubc30\uc5f4\uc744 dependency \uc5d0<\/h3>\n\n<div class=\"code-block\">function Component({ filters }) {\n  useEffect(() =&gt; { &#8230; }, [filters]);\n  \/\/ \ubd80\ubaa8\uac00 \ub9e4 \ub80c\ub354\ub9c8\ub2e4 \uc0c8 filters \uac1d\uccb4 \uc804\ub2ec \u2192 \ucc38\uc870 \ud56d\uc0c1 \uc0c8\uac83 \u2192 \ubb34\ud55c\n}<\/div>\n\n<p>\ud574\uacb0 \u2014 \ubd80\ubaa8\uac00 useMemo \ub85c \uac1d\uccb4 \uba54\ubaa8\uc774\uc988 (16\ud3b8), \ub610\ub294 \ud6a8\uacfc \uc548\uc5d0\uc11c \uac1d\uccb4\uc758 <strong>\uc6d0\uc2dc \uac12<\/strong>\ub9cc dependency \ub85c:<\/p>\n\n<div class=\"code-block\">useEffect(() =&gt; { &#8230; }, [filters.category, filters.minPrice]);<\/div>\n\n<h3>\ud568\uc815 3 \u2014 state \ub97c \ub2e4\ub978 state \ub85c \ub3d9\uae30\ud654<\/h3>\n\n<div class=\"code-block\">\/\/ \u274c \uc548\ud2f0\ud328\ud134\nuseEffect(() =&gt; {\n  setFullName(`${first} ${last}`);\n}, [first, last]);\n\n\/\/ \u2705 \uadf8\ub0e5 \ub80c\ub354 \uc911\uc5d0 \uacc4\uc0b0\nconst fullName = `${first} ${last}`;<\/div>\n\n<p>\uc774\uac74 \ubb34\ud55c \ub8e8\ud504\ub294 \uc548 \uc77c\uc5b4\ub098\uc9c0\ub9cc \ubd88\ud544\uc694\ud55c \uc7ac\ub80c\ub354 2\ubc88. <strong>&#8220;\ud30c\uc0dd \uac12\uc740 effect \uac00 \uc544\ub2c8\ub77c \uacc4\uc0b0&#8221;<\/strong> \uc774 React \uc758 \uc815\uacf5\ubc95. effect \ub294 \uc678\ubd80 \uc138\uacc4 \ub3d9\uae30\ud654 \uc804\uc6a9.<\/p>\n\n<div class=\"warnbox\">\n<strong>\uc694\uc998 \ud2b8\ub80c\ub4dc<\/strong> \u2014 \ub2e8\uc21c \ub370\uc774\ud130 fetch \ub294 useEffect \ub300\uc2e0 <strong>TanStack Query<\/strong> \ub610\ub294 <strong>SWR<\/strong> \uac19\uc740 \ub77c\uc774\ube0c\ub7ec\ub9ac\uac00 \ud45c\uc900. \uce90\uc2f1\u00b7\uc7ac\uc2dc\ub3c4\u00b7\uc911\ubcf5 \ud638\ucd9c \ubc29\uc9c0\u00b7\ub85c\ub529 \uc0c1\ud0dc \ubaa8\ub450 \uc81c\uacf5. 17\ud3b8 Suspense + \ub370\uc774\ud130 fetch \uc5d0\uc11c \ub2e4\uc2dc \ub4f1\uc7a5. \uadf8\ub798\ub3c4 useEffect \uc758 \uae30\ubcf8\uc740 \uc54c\uc544\uc57c \u2014 \uadf8 \ub77c\uc774\ube0c\ub7ec\ub9ac\ub3c4 \ub0b4\ubd80\uc5d0 effect \uac00 \uc788\ub2e4.\n<\/div>\n\n<p>useEffect \uac00 \uc190\uc5d0 \uc7a1\ud788\uba74 \uc778\ud130\ub799\ud2f0\ube0c React \uc571\uc758 \ubaa8\ub4e0 \ubd80\ud488\uc774 \uc644\uc131. 12\ud3b8\ubd80\ud130\ub294 \uac19\uc740 \ub85c\uc9c1\uc744 \uc5ec\ub7ec \ucef4\ud3ec\ub10c\ud2b8\uc5d0\uc11c \uc7ac\uc0ac\uc6a9\ud558\ub294 <strong>\ucee4\uc2a4\ud140 Hook<\/strong> \ud328\ud134. React \uc758 \uc9c4\uc9dc \uc6b0\uc544\ud568\uc774 \ubcf4\uc774\ub294 \uad6c\uac04.<\/p>\n\n<div class=\"cta\">\n<h3>\ub2e4\uc74c \uae00<\/h3>\n<p>React \uad50\uc7ac 12\ud3b8 \u2014 \ucee4\uc2a4\ud140 Hook \ub9cc\ub4e4\uae30. use- prefix, \ub85c\uc9c1 \ucd94\ucd9c, \uc7ac\uc0ac\uc6a9 \ud328\ud134. useEffect \uc758 \uc9c4\uc9dc \uc751\uc6a9.<\/p>\n<\/div>\n\n<div class=\"footer-nav\">\nReact \uad50\uc7ac \uc2dc\ub9ac\uc988 \u00b7\n<a href=\"https:\/\/junai.ai\/blog\/react-list-rendering-9\/\">9\ud3b8 \ub9ac\uc2a4\ud2b8<\/a> \u00b7\n<a href=\"https:\/\/junai.ai\/blog\/react-forms-10\/\">10\ud3b8 Form<\/a> \u00b7\n<strong>11\ud3b8 useEffect<\/strong>\n<\/div>\n\n<\/article>\n<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>React useEffect \u2014 dependency array, cleanup, \ubb34\ud55c \ub8e8\ud504 \ud568\uc815 3\uc885, \ub370\uc774\ud130 fetch \ud328\ud134. \ud55c\uad6d\uc5b4 \uad50\uc7ac 11\ud3b8.<\/p>\n","protected":false},"author":1,"featured_media":747,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[22],"tags":[],"class_list":["post-772","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\/772","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=772"}],"version-history":[{"count":1,"href":"https:\/\/junai.ai\/blog\/wp-json\/wp\/v2\/posts\/772\/revisions"}],"predecessor-version":[{"id":800,"href":"https:\/\/junai.ai\/blog\/wp-json\/wp\/v2\/posts\/772\/revisions\/800"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/junai.ai\/blog\/wp-json\/wp\/v2\/media\/747"}],"wp:attachment":[{"href":"https:\/\/junai.ai\/blog\/wp-json\/wp\/v2\/media?parent=772"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/junai.ai\/blog\/wp-json\/wp\/v2\/categories?post=772"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/junai.ai\/blog\/wp-json\/wp\/v2\/tags?post=772"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}