{"id":11459,"date":"2026-03-13T11:59:21","date_gmt":"2026-03-13T02:59:21","guid":{"rendered":"https:\/\/www.skyer9.pe.kr\/wordpress\/?p=11459"},"modified":"2026-03-13T13:31:31","modified_gmt":"2026-03-13T04:31:31","slug":"react-%ec%9e%85%eb%ac%b8%ec%9e%90%eb%a5%bc-%ec%9c%84%ed%95%9c-%ea%b8%b0%ec%b4%88-%ea%b0%80%ec%9d%b4%eb%93%9c","status":"publish","type":"post","link":"https:\/\/www.skyer9.pe.kr\/wordpress\/?p=11459","title":{"rendered":"React \uc785\ubb38\uc790\ub97c \uc704\ud55c \uae30\ucd08 \uac00\uc774\ub4dc"},"content":{"rendered":"<h1>React \uc785\ubb38\uc790\ub97c \uc704\ud55c \uae30\ucd08 \uac00\uc774\ub4dc<\/h1>\n<blockquote>\n<p>&quot;UI\ub97c \ub9cc\ub4dc\ub294 \uac00\uc7a5 \uc778\uae30 \uc788\ub294 \ubc29\ubc95&quot; \u2014 React\ub97c \ucc98\uc74c \uc811\ud558\ub294 \ubd84\ub4e4\uc744 \uc704\ud55c \uce5c\uc808\ud55c \uc785\ubb38\uc11c\uc785\ub2c8\ub2e4.<\/p>\n<\/blockquote>\n<h2>1. React\ub780 \ubb34\uc5c7\uc778\uac00?<\/h2>\n<p>React\ub294 Facebook(\ud604 Meta)\uc774 \ub9cc\ub4e0 <strong>JavaScript UI \ub77c\uc774\ube0c\ub7ec\ub9ac<\/strong>\uc785\ub2c8\ub2e4. \uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc758 \ud654\uba74(View)\uc744 \ub9cc\ub4dc\ub294 \ub370 \ud2b9\ud654\ub418\uc5b4 \uc788\uc73c\uba70, \uc804 \uc138\uacc4\uc5d0\uc11c \uac00\uc7a5 \ub110\ub9ac \uc0ac\uc6a9\ub418\ub294 \ud504\ub860\ud2b8\uc5d4\ub4dc \uae30\uc220 \uc911 \ud558\ub098\uc785\ub2c8\ub2e4.<\/p>\n<h3>React\uc758 \ud575\uc2ec \ucca0\ud559<\/h3>\n<p><strong>\ucef4\ud3ec\ub10c\ud2b8 \uae30\ubc18(Component-Based)<\/strong><br \/>\n\ud654\uba74\uc744 \ub3c5\ub9bd\uc801\uc778 \uc870\uac01(\ucef4\ud3ec\ub10c\ud2b8)\uc73c\ub85c \ub098\ub204\uc5b4 \uac1c\ubc1c\ud569\ub2c8\ub2e4. \ub808\uace0 \ube14\ub85d\ucc98\ub7fc \uac01\uac01\uc758 \ucef4\ud3ec\ub10c\ud2b8\ub97c \uc870\ud569\ud574 \ubcf5\uc7a1\ud55c UI\ub97c \ub9cc\ub4e4 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n<p><strong>\uc120\uc5b8\ud615(Declarative)<\/strong><br \/>\n&quot;\uc5b4\ub5bb\uac8c \ud654\uba74\uc744 \uadf8\ub9b4\uc9c0&quot;\uac00 \uc544\ub2c8\ub77c &quot;\ud654\uba74\uc774 \uc5b4\ub5a4 \uc0c1\ud0dc\uc5ec\uc57c \ud558\ub294\uc9c0&quot;\ub97c \uc120\uc5b8\ud569\ub2c8\ub2e4. \ub370\uc774\ud130\uac00 \ubc14\ub00c\uba74 React\uac00 \uc54c\uc544\uc11c \ud654\uba74\uc744 \uc5c5\ub370\uc774\ud2b8\ud574 \uc90d\ub2c8\ub2e4.<\/p>\n<p><strong>Virtual DOM<\/strong><br \/>\nReact\ub294 \uc2e4\uc81c DOM\uc744 \uc9c1\uc811 \uc870\uc791\ud558\uc9c0 \uc54a\uace0, \uba54\ubaa8\ub9ac \uc548\uc758 \uac00\uc0c1 DOM(Virtual DOM)\uc744 \uba3c\uc800 \uc5c5\ub370\uc774\ud2b8\ud55c \ub4a4 \uc2e4\uc81c \ubcc0\uacbd \uc0ac\ud56d\ub9cc \ud6a8\uc728\uc801\uc73c\ub85c \ubc18\uc601\ud569\ub2c8\ub2e4. \ub355\ubd84\uc5d0 \uc131\ub2a5\uc774 \ub6f0\uc5b4\ub0a9\ub2c8\ub2e4.<\/p>\n<h2>2. \uac1c\ubc1c \ud658\uacbd \uc124\uc815<\/h2>\n<h3>\ud544\uc218 \uc900\ube44\ubb3c<\/h3>\n<ul>\n<li><strong>Node.js<\/strong> (v18 \uc774\uc0c1 \uad8c\uc7a5) \u2014 <a href=\"https:\/\/nodejs.org\">nodejs.org<\/a>\uc5d0\uc11c \ub2e4\uc6b4\ub85c\ub4dc<\/li>\n<li><strong>\ucf54\ub4dc \uc5d0\ub514\ud130<\/strong> \u2014 VS Code \ucd94\ucc9c<\/li>\n<li><strong>\ud130\ubbf8\ub110<\/strong> \uc0ac\uc6a9\ubc95 \uae30\ucd08<\/li>\n<\/ul>\n<h3>\ud504\ub85c\uc81d\ud2b8 \uc0dd\uc131<\/h3>\n<p>\uac00\uc7a5 \ube60\ub974\uac8c React \ud504\ub85c\uc81d\ud2b8\ub97c \uc2dc\uc791\ud558\ub294 \ubc29\ubc95\uc740 <strong>Vite<\/strong>\ub97c \uc0ac\uc6a9\ud558\ub294 \uac83\uc785\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-bash\"># Vite\ub85c React \ud504\ub85c\uc81d\ud2b8 \uc0dd\uc131\nnpm create vite@latest my-react-app -- --template react\n\n# \ud504\ub85c\uc81d\ud2b8 \ud3f4\ub354\ub85c \uc774\ub3d9\ncd my-react-app\n\n# \ud328\ud0a4\uc9c0 \uc124\uce58\nnpm install\n\n# \uac1c\ubc1c \uc11c\ubc84 \uc2e4\ud589\nnpm run dev<\/code><\/pre>\n<p>\ube0c\ub77c\uc6b0\uc800\uc5d0\uc11c <code>http:\/\/localhost:5173<\/code>\uc744 \uc5f4\uba74 React \uc571\uc774 \uc2e4\ud589\ub429\ub2c8\ub2e4! \ud83c\udf89<\/p>\n<h3>\ud504\ub85c\uc81d\ud2b8 \uad6c\uc870 \uc0b4\ud3b4\ubcf4\uae30<\/h3>\n<pre><code>my-react-app\/\n\u251c\u2500\u2500 public\/          # \uc815\uc801 \ud30c\uc77c (\uc774\ubbf8\uc9c0, \ud3f0\ud2b8 \ub4f1)\n\u251c\u2500\u2500 src\/\n\u2502   \u251c\u2500\u2500 App.jsx      # \ub8e8\ud2b8 \ucef4\ud3ec\ub10c\ud2b8\n\u2502   \u251c\u2500\u2500 App.css      # \uc2a4\ud0c0\uc77c\n\u2502   \u2514\u2500\u2500 main.jsx     # \uc571\uc758 \uc9c4\uc785\uc810\n\u251c\u2500\u2500 index.html       # HTML \ud15c\ud50c\ub9bf\n\u2514\u2500\u2500 package.json     # \ud504\ub85c\uc81d\ud2b8 \uc124\uc815<\/code><\/pre>\n<h2>3. \uccab \ubc88\uc9f8 \ucef4\ud3ec\ub10c\ud2b8 \ub9cc\ub4e4\uae30<\/h2>\n<p>React\uc5d0\uc11c <strong>\ucef4\ud3ec\ub10c\ud2b8<\/strong>\ub294 UI\uc758 \uae30\ubcf8 \ub2e8\uc704\uc785\ub2c8\ub2e4. \ud568\uc218 \ud615\ud0dc\ub85c \uc791\uc131\ud558\uba70, JSX\ub97c \ubc18\ud658\ud569\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-jsx\">\/\/ src\/components\/Hello.jsx\n\nfunction Hello() {\n  return (\n    &lt;div&gt;\n      &lt;h1&gt;\uc548\ub155\ud558\uc138\uc694, React!&lt;\/h1&gt;\n      &lt;p&gt;\uccab \ubc88\uc9f8 \ucef4\ud3ec\ub10c\ud2b8\ub97c \ub9cc\ub4e4\uc5c8\uc2b5\ub2c8\ub2e4.&lt;\/p&gt;\n    &lt;\/div&gt;\n  );\n}\n\nexport default Hello;<\/code><\/pre>\n<p>\uc774 \ucef4\ud3ec\ub10c\ud2b8\ub97c <code>App.jsx<\/code>\uc5d0\uc11c \uc0ac\uc6a9\ud574\ubd05\uc2dc\ub2e4.<\/p>\n<pre><code class=\"language-jsx\">\/\/ src\/App.jsx\nimport Hello from &#039;.\/components\/Hello&#039;;\n\nfunction App() {\n  return (\n    &lt;div&gt;\n      &lt;Hello \/&gt;\n    &lt;\/div&gt;\n  );\n}\n\nexport default App;<\/code><\/pre>\n<h3>\ucef4\ud3ec\ub10c\ud2b8 \uc791\uc131 \uaddc\uce59<\/h3>\n<ul>\n<li>\ucef4\ud3ec\ub10c\ud2b8 \uc774\ub984\uc740 \ubc18\ub4dc\uc2dc <strong>\ub300\ubb38\uc790<\/strong>\ub85c \uc2dc\uc791\ud569\ub2c8\ub2e4 (<code>Hello<\/code>, <code>MyButton<\/code> \ub4f1)<\/li>\n<li>\ubc18\ub4dc\uc2dc <strong>\ud558\ub098\uc758 \ub8e8\ud2b8 \uc694\uc18c<\/strong>\ub97c \ubc18\ud658\ud574\uc57c \ud569\ub2c8\ub2e4<\/li>\n<li>\uc5ec\ub7ec \uc694\uc18c\ub97c \uac10\uc2f8\uace0 \uc2f6\uc744 \ub54c\ub294 <code>&lt;&gt;...&lt;\/&gt;<\/code> (Fragment)\ub97c \uc0ac\uc6a9\ud569\ub2c8\ub2e4<\/li>\n<\/ul>\n<pre><code class=\"language-jsx\">\/\/ Fragment \uc0ac\uc6a9 \uc608\uc2dc\nfunction MyComponent() {\n  return (\n    &lt;&gt;\n      &lt;h1&gt;\uc81c\ubaa9&lt;\/h1&gt;\n      &lt;p&gt;\ub0b4\uc6a9&lt;\/p&gt;\n    &lt;\/&gt;\n  );\n}<\/code><\/pre>\n<hr \/>\n<h2>4. JSX \uc774\ud574\ud558\uae30<\/h2>\n<p>JSX\ub294 JavaScript \uc548\uc5d0\uc11c HTML\ucc98\ub7fc UI\ub97c \uc791\uc131\ud560 \uc218 \uc788\uac8c \ud574\uc8fc\ub294 \ubb38\ubc95 \ud655\uc7a5\uc785\ub2c8\ub2e4. \uc2e4\uc81c\ub85c\ub294 JavaScript\ub85c \ubcc0\ud658\ub418\uc5b4 \uc2e4\ud589\ub429\ub2c8\ub2e4.<\/p>\n<h3>JSX\uc758 \ud575\uc2ec \uaddc\uce59<\/h3>\n<p><strong>\uc911\uad04\ud638 <code>{}<\/code>\ub85c JavaScript \ud45c\ud604\uc2dd \uc0bd\uc785<\/strong><\/p>\n<pre><code class=\"language-jsx\">const name = &#039;\ucca0\uc218&#039;;\nconst age = 25;\n\nfunction Profile() {\n  return (\n    &lt;div&gt;\n      &lt;p&gt;\uc774\ub984: {name}&lt;\/p&gt;\n      &lt;p&gt;\ub098\uc774: {age}&lt;\/p&gt;\n      &lt;p&gt;10\ub144 \ud6c4: {age + 10}\uc0b4&lt;\/p&gt;\n    &lt;\/div&gt;\n  );\n}<\/code><\/pre>\n<p><strong>HTML \uc18d\uc131\uc740 camelCase\ub85c \uc791\uc131<\/strong><\/p>\n<pre><code class=\"language-jsx\">\/\/ HTML            \u2192  JSX\n\/\/ class           \u2192  className\n\/\/ for             \u2192  htmlFor\n\/\/ onclick         \u2192  onClick\n\/\/ background-color \u2192 backgroundColor\n\n&lt;div className=&quot;container&quot;&gt;\n  &lt;label htmlFor=&quot;input&quot;&gt;\uc774\ub984&lt;\/label&gt;\n  &lt;input id=&quot;input&quot; type=&quot;text&quot; \/&gt;\n&lt;\/div&gt;<\/code><\/pre>\n<p><strong>\uc790\uae30 \ub2eb\ud798 \ud0dc\uadf8(Self-closing tag) \ud544\uc218<\/strong><\/p>\n<pre><code class=\"language-jsx\">\/\/ \u2705 \uc62c\ubc14\ub978 JSX\n&lt;img src=&quot;photo.jpg&quot; alt=&quot;\uc0ac\uc9c4&quot; \/&gt;\n&lt;input type=&quot;text&quot; \/&gt;\n&lt;br \/&gt;\n\n\/\/ \u274c \ud2c0\ub9b0 JSX\n&lt;img src=&quot;photo.jpg&quot;&gt;\n&lt;input type=&quot;text&quot;&gt;<\/code><\/pre>\n<h2>5. Props: \ucef4\ud3ec\ub10c\ud2b8\uc5d0 \ub370\uc774\ud130 \uc804\ub2ec\ud558\uae30<\/h2>\n<p><strong>Props(Properties)<\/strong>\ub294 \ubd80\ubaa8 \ucef4\ud3ec\ub10c\ud2b8\uc5d0\uc11c \uc790\uc2dd \ucef4\ud3ec\ub10c\ud2b8\ub85c \ub370\uc774\ud130\ub97c \uc804\ub2ec\ud558\ub294 \ubc29\ubc95\uc785\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-jsx\">\/\/ \uc790\uc2dd \ucef4\ud3ec\ub10c\ud2b8: props\ub97c \ubc1b\uc544 \uc0ac\uc6a9\nfunction UserCard({ name, age, job }) {\n  return (\n    &lt;div className=&quot;card&quot;&gt;\n      &lt;h2&gt;{name}&lt;\/h2&gt;\n      &lt;p&gt;\ub098\uc774: {age}\uc138&lt;\/p&gt;\n      &lt;p&gt;\uc9c1\uc5c5: {job}&lt;\/p&gt;\n    &lt;\/div&gt;\n  );\n}\n\n\/\/ \ubd80\ubaa8 \ucef4\ud3ec\ub10c\ud2b8: props\ub97c \uc804\ub2ec\nfunction App() {\n  return (\n    &lt;div&gt;\n      &lt;UserCard name=&quot;\uae40\ucca0\uc218&quot; age={28} job=&quot;\uac1c\ubc1c\uc790&quot; \/&gt;\n      &lt;UserCard name=&quot;\uc774\uc601\ud76c&quot; age={24} job=&quot;\ub514\uc790\uc774\ub108&quot; \/&gt;\n    &lt;\/div&gt;\n  );\n}<\/code><\/pre>\n<h3>\uc8fc\uc758\uc0ac\ud56d: Props\ub294 \uc77d\uae30 \uc804\uc6a9<\/h3>\n<p>Props\ub294 \uc790\uc2dd \ucef4\ud3ec\ub10c\ud2b8\uc5d0\uc11c <strong>\uc9c1\uc811 \uc218\uc815\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4<\/strong>. \ub370\uc774\ud130\uc758 \ud750\ub984\uc740 \ud56d\uc0c1 \ubd80\ubaa8 \u2192 \uc790\uc2dd \ubc29\ud5a5\uc785\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-jsx\">\/\/ \u274c \uc798\ubabb\ub41c \uc0ac\uc6a9 \u2014 props \uc9c1\uc811 \uc218\uc815 \uae08\uc9c0\nfunction BadComponent({ name }) {\n  name = &#039;\ud64d\uae38\ub3d9&#039;; \/\/ \uc774\ub807\uac8c \ud558\uba74 \uc548 \ub429\ub2c8\ub2e4!\n  return &lt;p&gt;{name}&lt;\/p&gt;;\n}<\/code><\/pre>\n<h2>6. State: \ubcc0\ud558\ub294 \ub370\uc774\ud130 \uad00\ub9ac\ud558\uae30<\/h2>\n<p><strong>State<\/strong>\ub294 \ucef4\ud3ec\ub10c\ud2b8 \ub0b4\ubd80\uc5d0\uc11c \uad00\ub9ac\ud558\ub294 \ub370\uc774\ud130\uc785\ub2c8\ub2e4. State\uac00 \ubcc0\ud558\uba74 React\uac00 \uc790\ub3d9\uc73c\ub85c \ud654\uba74\uc744 \ub2e4\uc2dc \ub80c\ub354\ub9c1\ud569\ub2c8\ub2e4.<\/p>\n<p><code>useState<\/code> Hook\uc744 \uc0ac\uc6a9\ud574 State\ub97c \ub9cc\ub4ed\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-jsx\">import { useState } from &#039;react&#039;;\n\nfunction Counter() {\n  \/\/ [\ud604\uc7ac \uac12, \uac12\uc744 \ubc14\uafb8\ub294 \ud568\uc218] = useState(\ucd08\uae30\uac12)\n  const [count, setCount] = useState(0);\n\n  return (\n    &lt;div&gt;\n      &lt;p&gt;\ud604\uc7ac \uce74\uc6b4\ud2b8: {count}&lt;\/p&gt;\n      &lt;button onClick={() =&gt; setCount(count + 1)}&gt;+1 \uc99d\uac00&lt;\/button&gt;\n      &lt;button onClick={() =&gt; setCount(count - 1)}&gt;-1 \uac10\uc18c&lt;\/button&gt;\n      &lt;button onClick={() =&gt; setCount(0)}&gt;\ucd08\uae30\ud654&lt;\/button&gt;\n    &lt;\/div&gt;\n  );\n}<\/code><\/pre>\n<h3>\uc5ec\ub7ec \uac1c\uc758 State \uc0ac\uc6a9\ud558\uae30<\/h3>\n<pre><code class=\"language-jsx\">import { useState } from &#039;react&#039;;\n\nfunction LoginForm() {\n  const [username, setUsername] = useState(&#039;&#039;);\n  const [password, setPassword] = useState(&#039;&#039;);\n\n  return (\n    &lt;form&gt;\n      &lt;input\n        type=&quot;text&quot;\n        value={username}\n        onChange={(e) =&gt; setUsername(e.target.value)}\n        placeholder=&quot;\uc544\uc774\ub514&quot;\n      \/&gt;\n      &lt;input\n        type=&quot;password&quot;\n        value={password}\n        onChange={(e) =&gt; setPassword(e.target.value)}\n        placeholder=&quot;\ube44\ubc00\ubc88\ud638&quot;\n      \/&gt;\n      &lt;p&gt;\uc785\ub825 \uc911\uc778 \uc544\uc774\ub514: {username}&lt;\/p&gt;\n    &lt;\/form&gt;\n  );\n}<\/code><\/pre>\n<h3>\u26a0\ufe0f \uc911\uc694: State\ub294 \uc9c1\uc811 \uc218\uc815\ud558\uc9c0 \uc54a\ub294\ub2e4<\/h3>\n<pre><code class=\"language-jsx\">const [count, setCount] = useState(0);\n\n\/\/ \u274c \uc798\ubabb\ub41c \ubc29\ubc95 \u2014 \uc9c1\uc811 \uc218\uc815\ncount = count + 1;\n\n\/\/ \u2705 \uc62c\ubc14\ub978 \ubc29\ubc95 \u2014 setter \ud568\uc218 \uc0ac\uc6a9\nsetCount(count + 1);<\/code><\/pre>\n<h2>7. \uc774\ubca4\ud2b8 \ucc98\ub9ac\ud558\uae30<\/h2>\n<p>React\uc5d0\uc11c \uc774\ubca4\ud2b8\ub294 HTML\uacfc \ube44\uc2b7\ud558\uc9c0\ub9cc \uba87 \uac00\uc9c0 \ucc28\uc774\uac00 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-jsx\">function ButtonExample() {\n  \/\/ \uc774\ubca4\ud2b8 \ud578\ub4e4\ub7ec \ud568\uc218 \uc815\uc758\n  const handleClick = () =&gt; {\n    alert(&#039;\ubc84\ud2bc\uc744 \ud074\ub9ad\ud588\uc2b5\ub2c8\ub2e4!&#039;);\n  };\n\n  const handleMouseEnter = () =&gt; {\n    console.log(&#039;\ub9c8\uc6b0\uc2a4\uac00 \uc62c\ub77c\uc654\uc2b5\ub2c8\ub2e4&#039;);\n  };\n\n  return (\n    &lt;div&gt;\n      {\/* onClick\uc5d0 \ud568\uc218\ub97c \uc804\ub2ec (\ud638\ucd9c\ud558\uc9c0 \uc54a\uc74c) *\/}\n      &lt;button onClick={handleClick}&gt;\ud074\ub9ad\ud558\uc138\uc694&lt;\/button&gt;\n\n      {\/* \uc778\ub77c\uc778 \ud654\uc0b4\ud45c \ud568\uc218 *\/}\n      &lt;button onClick={() =&gt; alert(&#039;\uc548\ub155!&#039;)}&gt;\uc778\ub77c\uc778&lt;\/button&gt;\n\n      {\/* \ub2e4\uc591\ud55c \uc774\ubca4\ud2b8 *\/}\n      &lt;div onMouseEnter={handleMouseEnter}&gt;\ub9c8\uc6b0\uc2a4\ub97c \uc62c\ub824\ubcf4\uc138\uc694&lt;\/div&gt;\n    &lt;\/div&gt;\n  );\n}<\/code><\/pre>\n<h3>\uc790\uc8fc \uc0ac\uc6a9\ud558\ub294 \uc774\ubca4\ud2b8<\/h3>\n<table>\n<thead>\n<tr>\n<th>\uc774\ubca4\ud2b8<\/th>\n<th>\uc124\uba85<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>onClick<\/code><\/td>\n<td>\ud074\ub9ad<\/td>\n<\/tr>\n<tr>\n<td><code>onChange<\/code><\/td>\n<td>\uc785\ub825\uac12 \ubcc0\uacbd<\/td>\n<\/tr>\n<tr>\n<td><code>onSubmit<\/code><\/td>\n<td>\ud3fc \uc81c\ucd9c<\/td>\n<\/tr>\n<tr>\n<td><code>onKeyDown<\/code> \/ <code>onKeyUp<\/code><\/td>\n<td>\ud0a4\ubcf4\ub4dc \uc785\ub825<\/td>\n<\/tr>\n<tr>\n<td><code>onMouseEnter<\/code> \/ <code>onMouseLeave<\/code><\/td>\n<td>\ub9c8\uc6b0\uc2a4 \uc9c4\uc785\/\uc774\ud0c8<\/td>\n<\/tr>\n<tr>\n<td><code>onFocus<\/code> \/ <code>onBlur<\/code><\/td>\n<td>\ud3ec\ucee4\uc2a4 \uc5bb\uc74c\/\uc783\uc74c<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>8. \uc870\uac74\ubd80 \ub80c\ub354\ub9c1<\/h2>\n<p>\ub370\uc774\ud130\uc5d0 \ub530\ub77c \ub2e4\ub978 UI\ub97c \ubcf4\uc5ec\uc8fc\uace0 \uc2f6\uc744 \ub54c \uc870\uac74\ubd80 \ub80c\ub354\ub9c1\uc744 \uc0ac\uc6a9\ud569\ub2c8\ub2e4.<\/p>\n<h3>\ubc29\ubc95 1: if\ubb38 \uc0ac\uc6a9<\/h3>\n<pre><code class=\"language-jsx\">function Greeting({ isLoggedIn }) {\n  if (isLoggedIn) {\n    return &lt;h1&gt;\ub3cc\uc544\uc624\uc168\uad70\uc694!&lt;\/h1&gt;;\n  }\n  return &lt;h1&gt;\uba3c\uc800 \ub85c\uadf8\uc778\ud574\uc8fc\uc138\uc694.&lt;\/h1&gt;;\n}<\/code><\/pre>\n<h3>\ubc29\ubc95 2: \uc0bc\ud56d \uc5f0\uc0b0\uc790 (JSX \uc548\uc5d0\uc11c \uc0ac\uc6a9)<\/h3>\n<pre><code class=\"language-jsx\">function UserStatus({ isOnline }) {\n  return (\n    &lt;div&gt;\n      &lt;span style={{ color: isOnline ? &#039;green&#039; : &#039;gray&#039; }}&gt;\n        {isOnline ? &#039;\ud83d\udfe2 \uc628\ub77c\uc778&#039; : &#039;\u26ab \uc624\ud504\ub77c\uc778&#039;}\n      &lt;\/span&gt;\n    &lt;\/div&gt;\n  );\n}<\/code><\/pre>\n<h3>\ubc29\ubc95 3: &amp;&amp; \uc5f0\uc0b0\uc790 (\uc870\uac74\uc774 \ucc38\uc77c \ub54c\ub9cc \ud45c\uc2dc)<\/h3>\n<pre><code class=\"language-jsx\">function Notification({ hasMessage, messageCount }) {\n  return (\n    &lt;div&gt;\n      &lt;h1&gt;\ubc1b\uc740 \ud3b8\uc9c0\ud568&lt;\/h1&gt;\n      {hasMessage &amp;&amp; (\n        &lt;p&gt;\uc77d\uc9c0 \uc54a\uc740 \uba54\uc2dc\uc9c0\uac00 {messageCount}\uac1c \uc788\uc2b5\ub2c8\ub2e4.&lt;\/p&gt;\n      )}\n    &lt;\/div&gt;\n  );\n}<\/code><\/pre>\n<h2>9. \ub9ac\uc2a4\ud2b8 \ub80c\ub354\ub9c1<\/h2>\n<p>\ubc30\uc5f4 \ub370\uc774\ud130\ub97c \ud654\uba74\uc5d0 \ub098\uc5f4\ud560 \ub54c\ub294 <code>map()<\/code> \uba54\uc11c\ub4dc\ub97c \uc0ac\uc6a9\ud569\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-jsx\">function TodoList() {\n  const todos = [\n    { id: 1, text: &#039;React \uacf5\ubd80\ud558\uae30&#039;, done: true },\n    { id: 2, text: &#039;\ucef4\ud3ec\ub10c\ud2b8 \ub9cc\ub4e4\uae30&#039;, done: false },\n    { id: 3, text: &#039;\ud504\ub85c\uc81d\ud2b8 \uc644\uc131\ud558\uae30&#039;, done: false },\n  ];\n\n  return (\n    &lt;ul&gt;\n      {todos.map((todo) =&gt; (\n        &lt;li\n          key={todo.id}\n          style={{ textDecoration: todo.done ? &#039;line-through&#039; : &#039;none&#039; }}\n        &gt;\n          {todo.text}\n        &lt;\/li&gt;\n      ))}\n    &lt;\/ul&gt;\n  );\n}<\/code><\/pre>\n<h3>\u26a0\ufe0f <code>key<\/code> prop\uc740 \ud544\uc218<\/h3>\n<p>\ub9ac\uc2a4\ud2b8\ub97c \ub80c\ub354\ub9c1\ud560 \ub54c\ub294 \ubc18\ub4dc\uc2dc \uac01 \ud56d\ubaa9\uc5d0 <strong>\uace0\uc720\ud55c <code>key<\/code><\/strong> \ub97c \ubd80\uc5ec\ud574\uc57c \ud569\ub2c8\ub2e4. React\uac00 \uc5b4\ub5a4 \ud56d\ubaa9\uc774 \ubcc0\uacbd\ub418\uc5c8\ub294\uc9c0 \ud6a8\uc728\uc801\uc73c\ub85c \ud30c\uc545\ud558\uae30 \uc704\ud574 \uc0ac\uc6a9\ud569\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-jsx\">\/\/ \u2705 \uc88b\uc740 \uc608: \uace0\uc720\ud55c id \uc0ac\uc6a9\n{items.map((item) =&gt; &lt;li key={item.id}&gt;{item.name}&lt;\/li&gt;)}\n\n\/\/ \u26a0\ufe0f \uad8c\uc7a5\ud558\uc9c0 \uc54a\uc74c: \uc778\ub371\uc2a4 \uc0ac\uc6a9 (\uc21c\uc11c\uac00 \ubc14\ub00c\uba74 \ubb38\uc81c \ubc1c\uc0dd \uac00\ub2a5)\n{items.map((item, index) =&gt; &lt;li key={index}&gt;{item.name}&lt;\/li&gt;)}<\/code><\/pre>\n<h2>10. useEffect: \uc0ac\uc774\ub4dc \uc774\ud399\ud2b8 \ub2e4\ub8e8\uae30<\/h2>\n<p><strong>useEffect<\/strong>\ub294 \ucef4\ud3ec\ub10c\ud2b8\uac00 \ub80c\ub354\ub9c1\ub41c \ud6c4 \uc2e4\ud589\ud560 \uc791\uc5c5\uc744 \uc9c0\uc815\ud558\ub294 Hook\uc785\ub2c8\ub2e4. API \ud638\ucd9c, \uc774\ubca4\ud2b8 \uad6c\ub3c5, \ud0c0\uc774\uba38 \uc124\uc815 \ub4f1\uc5d0 \uc0ac\uc6a9\ud569\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-jsx\">import { useState, useEffect } from &#039;react&#039;;\n\nfunction UserProfile({ userId }) {\n  const [user, setUser] = useState(null);\n  const [loading, setLoading] = useState(true);\n\n  useEffect(() =&gt; {\n    \/\/ userId\uac00 \ubc14\ub014 \ub54c\ub9c8\ub2e4 \uc2e4\ud589\n    setLoading(true);\n\n    fetch(`https:\/\/api.example.com\/users\/${userId}`)\n      .then((res) =&gt; res.json())\n      .then((data) =&gt; {\n        setUser(data);\n        setLoading(false);\n      });\n  }, [userId]); \/\/ \uc758\uc874\uc131 \ubc30\uc5f4: userId\uac00 \ubc14\ub014 \ub54c\ub9cc \uc2e4\ud589\n\n  if (loading) return &lt;p&gt;\ub85c\ub529 \uc911...&lt;\/p&gt;;\n  if (!user) return &lt;p&gt;\uc0ac\uc6a9\uc790\ub97c \ucc3e\uc744 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.&lt;\/p&gt;;\n\n  return (\n    &lt;div&gt;\n      &lt;h2&gt;{user.name}&lt;\/h2&gt;\n      &lt;p&gt;{user.email}&lt;\/p&gt;\n    &lt;\/div&gt;\n  );\n}<\/code><\/pre>\n<h3>\uc758\uc874\uc131 \ubc30\uc5f4(Dependency Array) \uc774\ud574\ud558\uae30<\/h3>\n<pre><code class=\"language-jsx\">\/\/ 1. \ub80c\ub354\ub9c1\ub420 \ub54c\ub9c8\ub2e4 \uc2e4\ud589\nuseEffect(() =&gt; {\n  console.log(&#039;\ub9e4\ubc88 \uc2e4\ud589&#039;);\n});\n\n\/\/ 2. \ucc98\uc74c \ud55c \ubc88\ub9cc \uc2e4\ud589 (\ucef4\ud3ec\ub10c\ud2b8 \ub9c8\uc6b4\ud2b8 \uc2dc)\nuseEffect(() =&gt; {\n  console.log(&#039;\ucc98\uc74c \ud55c \ubc88\ub9cc \uc2e4\ud589&#039;);\n}, []);\n\n\/\/ 3. value\uac00 \ubcc0\uacbd\ub420 \ub54c\ub9c8\ub2e4 \uc2e4\ud589\nuseEffect(() =&gt; {\n  console.log(&#039;value\uac00 \ubc14\ub014 \ub54c \uc2e4\ud589:&#039;, value);\n}, [value]);<\/code><\/pre>\n<h3>\ud074\ub9b0\uc5c5(Cleanup) \ud568\uc218<\/h3>\n<p>\ucef4\ud3ec\ub10c\ud2b8\uac00 \uc0ac\ub77c\uc9c8 \ub54c \uc815\ub9ac \uc791\uc5c5\uc774 \ud544\uc694\ud558\ub2e4\uba74 <code>return<\/code>\uc73c\ub85c \ud568\uc218\ub97c \ubc18\ud658\ud569\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-jsx\">useEffect(() =&gt; {\n  const timer = setInterval(() =&gt; {\n    console.log(&#039;1\ucd08\ub9c8\ub2e4 \uc2e4\ud589&#039;);\n  }, 1000);\n\n  \/\/ \ucef4\ud3ec\ub10c\ud2b8\uac00 \uc0ac\ub77c\uc9c8 \ub54c \ud0c0\uc774\uba38 \uc815\ub9ac\n  return () =&gt; clearInterval(timer);\n}, []);<\/code><\/pre>\n<h2>11. \ub2e4\uc74c \ub2e8\uacc4\ub85c \ub098\uc544\uac00\uae30<\/h2>\n<p>React \uae30\ucd08\ub97c \uc775\ud614\ub2e4\uba74 \ub2e4\uc74c \uc8fc\uc81c\ub4e4\uc744 \uacf5\ubd80\ud574\ubcf4\uc138\uc694!<\/p>\n<h3>\ud83d\udd11 \uc911\uc694 Hook\ub4e4<\/h3>\n<table>\n<thead>\n<tr>\n<th>Hook<\/th>\n<th>\uc6a9\ub3c4<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>useContext<\/code><\/td>\n<td>\uc804\uc5ed \ub370\uc774\ud130 \uacf5\uc720<\/td>\n<\/tr>\n<tr>\n<td><code>useReducer<\/code><\/td>\n<td>\ubcf5\uc7a1\ud55c \uc0c1\ud0dc \uad00\ub9ac<\/td>\n<\/tr>\n<tr>\n<td><code>useRef<\/code><\/td>\n<td>DOM \uc9c1\uc811 \uc811\uadfc<\/td>\n<\/tr>\n<tr>\n<td><code>useMemo<\/code><\/td>\n<td>\uacc4\uc0b0 \uacb0\uacfc \uce90\uc2f1<\/td>\n<\/tr>\n<tr>\n<td><code>useCallback<\/code><\/td>\n<td>\ud568\uc218 \uce90\uc2f1<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3>\ud83d\udcda \ud568\uaed8 \ubc30\uc6b0\uba74 \uc88b\uc740 \uae30\uc220<\/h3>\n<ul>\n<li><strong>React Router<\/strong> \u2014 \ud398\uc774\uc9c0 \uc774\ub3d9(\ub77c\uc6b0\ud305) \ucc98\ub9ac<\/li>\n<li><strong>Zustand \ub610\ub294 Redux<\/strong> \u2014 \uc804\uc5ed \uc0c1\ud0dc \uad00\ub9ac<\/li>\n<li><strong>React Query (TanStack Query)<\/strong> \u2014 \uc11c\ubc84 \ub370\uc774\ud130 \uad00\ub9ac<\/li>\n<li><strong>TypeScript<\/strong> \u2014 \ud0c0\uc785 \uc548\uc804\uc131 \ucd94\uac00<\/li>\n<li><strong>Next.js<\/strong> \u2014 \uc11c\ubc84 \uc0ac\uc774\ub4dc \ub80c\ub354\ub9c1(SSR) \ud504\ub808\uc784\uc6cc\ud06c<\/li>\n<\/ul>\n<h3>\ud83c\udf10 \uacf5\uc2dd \ud559\uc2b5 \uc790\ub8cc<\/h3>\n<ul>\n<li><a href=\"https:\/\/react.dev\">React \uacf5\uc2dd \ubb38\uc11c<\/a> \u2014 \ud55c\uad6d\uc5b4 \uc9c0\uc6d0, \ucd5c\uace0\uc758 \ub808\ud37c\ub7f0\uc2a4<\/li>\n<li><a href=\"https:\/\/react.dev\/learn\">React \uacf5\uc2dd \ud29c\ud1a0\ub9ac\uc5bc<\/a> \u2014 \ud2f1\ud0dd\ud1a0 \uac8c\uc784 \ub9cc\ub4e4\uae30<\/li>\n<li><a href=\"https:\/\/vitejs.dev\">Vite \uacf5\uc2dd \ubb38\uc11c<\/a> \u2014 \ube60\ub978 \uac1c\ubc1c \ud658\uacbd<\/li>\n<\/ul>\n<h2>\ub9c8\uce58\uba70<\/h2>\n<p>Zustand + TanStack Query + React Hook Form + Zod + Tailwind + shadcn\/ui<\/p>\n","protected":false},"excerpt":{"rendered":"<p>React \uc785\ubb38\uc790\ub97c \uc704\ud55c \uae30\ucd08 \uac00\uc774\ub4dc &quot;UI\ub97c \ub9cc\ub4dc\ub294 \uac00\uc7a5 \uc778\uae30 \uc788\ub294 \ubc29\ubc95&quot; \u2014 React\ub97c \ucc98\uc74c \uc811\ud558\ub294 \ubd84\ub4e4\uc744 \uc704\ud55c \uce5c\uc808\ud55c \uc785\ubb38\uc11c\uc785\ub2c8\ub2e4. 1. React\ub780 \ubb34\uc5c7\uc778\uac00? React\ub294 Facebook(\ud604 Meta)\uc774 \ub9cc\ub4e0 JavaScript UI \ub77c\uc774\ube0c\ub7ec\ub9ac\uc785\ub2c8\ub2e4. \uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc758 \ud654\uba74(View)\uc744 \ub9cc\ub4dc\ub294 \ub370 \ud2b9\ud654\ub418\uc5b4 \uc788\uc73c\uba70, \uc804 \uc138\uacc4\uc5d0\uc11c \uac00\uc7a5 \ub110\ub9ac \uc0ac\uc6a9\ub418\ub294 \ud504\ub860\ud2b8\uc5d4\ub4dc \uae30\uc220 \uc911 \ud558\ub098\uc785\ub2c8\ub2e4. React\uc758 \ud575\uc2ec \ucca0\ud559 \ucef4\ud3ec\ub10c\ud2b8 \uae30\ubc18(Component-Based) \ud654\uba74\uc744 \ub3c5\ub9bd\uc801\uc778 \uc870\uac01(\ucef4\ud3ec\ub10c\ud2b8)\uc73c\ub85c \ub098\ub204\uc5b4 \uac1c\ubc1c\ud569\ub2c8\ub2e4.\u2026 <span class=\"read-more\"><a href=\"https:\/\/www.skyer9.pe.kr\/wordpress\/?p=11459\">Read More &raquo;<\/a><\/span><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[22],"tags":[],"class_list":["post-11459","post","type-post","status-publish","format-standard","hentry","category-web"],"_links":{"self":[{"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/11459","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=11459"}],"version-history":[{"count":3,"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/11459\/revisions"}],"predecessor-version":[{"id":11462,"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/11459\/revisions\/11462"}],"wp:attachment":[{"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=11459"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=11459"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=11459"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}