๐Ÿ“˜ [Recat] React ํ•ต์‹ฌ - ์ปดํฌ๋„ŒํŠธ, JSX, ์†์„ฑ, ์ƒํƒœ ๋“ฑ - 2

๐Ÿ“˜ [Recat] React ํ•ต์‹ฌ - ์ปดํฌ๋„ŒํŠธ, JSX, ์†์„ฑ, ์ƒํƒœ ๋“ฑ - 2

[Recat] React ํ•ต์‹ฌ - ์ปดํฌ๋„ŒํŠธ, JSX, ์†์„ฑ, ์ƒํƒœ ๋“ฑ - 2

ํŒŒ์ผ์— ์ปดํฌ๋„ŒํŠธ ์ €์žฅ ๋ฐ ์ข‹์€ ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ ํ™œ์šฉ

1. ์ปดํฌ๋„ŒํŠธ ํŒŒ์ผ ๋ถ„๋ฆฌ

๊ธฐ์กด์˜ App.jsx์— ์ƒ์„ฑํ–ˆ๋˜ ์ปดํฌ๋„ŒํŠธ๋“ค์„ ๋ถ„๋ฆฌ๋œ ํŒŒ์ผ๋กœ ๊ด€๋ฆฌํ•˜์—ฌ ์ฝ”๋“œ์˜ ๊ตฌ์กฐํ™” ๋ฐ ์œ ์ง€๋ณด์ˆ˜์„ฑ์„ ํ–ฅ์ƒ์‹œํ‚ค๊ธฐ ์œ„ํ•จ

  • Header.jsx์™€ CoreConcept.jsx๋ฅผ components ํด๋”๋กœ ์ด๋™ ๋ฐ ์ €์žฅ
  • ๊ฐ ์ปดํฌ๋„ŒํŠธ๋Š” ํ•ด๋‹น ํŒŒ์ผ์—์„œ export default ๋ฌธ๋ฒ•์œผ๋กœ ๋‚ด๋ณด๋ƒ„
    • ์˜ˆ: export default function Header() {...}

2. App.jsx์—์„œ ์ปดํฌ๋„ŒํŠธ ์žฌ์‚ฌ์šฉ

  • App.jsx์—์„œ Header, CoreConcept๋ฅผ import
import { CORE_CONCEPTS } from "./data.js";
import Header from "./components/Header.jsx";
import CoreConcept from "./components/CoreConcept.jsx";

์ปดํฌ๋„ŒํŠธ ์˜†์— ์ปดํฌ๋„ŒํŠธ ์Šคํƒ€์ผ ํŒŒ์ผ ์ €์žฅํ•˜๊ธฐ

  • ๊ด€๋ จ ํŒŒ์ผ(Header.jsx, Header.css)์„ ๊ฐ™์€ ํด๋”์— ๋ฌถ์–ด ๊ด€๋ฆฌ
  • ์ปดํฌ๋„ŒํŠธ๋ณ„ ์ •๋ฆฌ๋กœ ์œ ์ง€๋ณด์ˆ˜์„ฑ๊ณผ ๊ตฌ์กฐ ์ดํ•ด๋„ ํ–ฅ์ƒ
import './Header.css';

โœ… ์ ์šฉ ๋ฐฉ์‹ ์ฃผ์˜์‚ฌํ•ญ

  • CSS๋Š” ์ „์—ญ ๋ฒ”์œ„๋กœ ์ ์šฉ๋˜๋ฉฐ, ๋‹จ์ˆœํžˆ Header.css๋ฅผ Header.jsx์—์„œ importํ•œ๋‹ค๊ณ  ํ•ด์„œ ํ•ด๋‹น ์Šคํƒ€์ผ์ด ๊ทธ ์ปดํฌ๋„ŒํŠธ์—๋งŒ ์ž๋™ ํ•œ์ •๋˜์ง€๋Š” ์•Š์Œ.
  • ์˜ˆ: <h1> ์Šคํƒ€์ผ์ด ์ •์˜๋˜์–ด ์žˆ๋‹ค๋ฉด, ๋ชจ๋“  <h1> ์š”์†Œ์— ์ ์šฉ๋จ.
  • ์Šคํƒ€์ผ์„ ์ปดํฌ๋„ŒํŠธ๋ณ„๋กœ ๋ถ„๋ฆฌํ•˜๋ฉด ๊ด€๋ฆฌ๊ฐ€ ์‰ฌ์›Œ์ง€๊ณ  ๋ช…ํ™•ํ•œ ๊ตฌ์กฐ๋ฅผ ๊ฐ–์ถœ ์ˆ˜ ์žˆ์Œ
  • ๋‹ค๋งŒ CSS๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์ „์—ญ ์ ์šฉ๋˜๋ฏ€๋กœ, ์ดํ›„ ๊ฐ•์˜์—์„œ ์†Œ๊ฐœ๋  CSS ๋ชจ๋“ˆ ๋˜๋Š” CSS-in-JS์™€ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์Šคํƒ€์ผ ๋ฒ”์œ„ ์ œํ•œ์„ ์ ์šฉํ•  ์ˆ˜ ์žˆ์Œ

์ปดํฌ๋„ŒํŠธ ๊ตฌ์„ฑ : children prop ์†์„ฑ

๋ฆฌ์•กํŠธ์—์„œ๋Š” <TabButton>Components</TabButton>์™€ ๊ฐ™์ด ์ปดํฌ๋„ŒํŠธ ํƒœ๊ทธ ์‚ฌ์ด์— ๋‚ด์šฉ์„ ์ž‘์„ฑํ•˜๋ฉด, ๊ทธ ๋‚ด์šฉ์€ children prop์œผ๋กœ ์ „๋‹ฌ๋จ

export default function TabButton({ children } ๋˜๋Š” props) {
  return <li><button>{children}๋˜๋Š”{props.children}</button></li>;
}

children vs label ๋ฐฉ์‹ ๋น„๊ต

  • ๋‘ ๋ฐฉ์‹ ๋ชจ๋‘ ๋ฒ„ํŠผ ํ…์ŠคํŠธ๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Œ

๋ฐฉ์‹ 1: children ๋ฐฉ์‹

<TabButton>Components</TabButton>

๋ฐฉ์‹ 2: ๋ช…์‹œ์  props ๋ฐฉ์‹

<TabButton label="Components" />
// ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์—์„œ: <button>{props.label}</button>

์ด๋ฒคํŠธ ์ฒ˜๋ฆฌํ•˜๊ธฐ

  • ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ํ•จ์ˆ˜๋Š” ๊ฐ’์„ ์ „๋‹ฌํ•ด์•ผ ํ•˜๋ฏ€๋กœ ํ•จ์ˆ˜ ์ด๋ฆ„๋งŒ ๋„˜๊น€
  • onClick={handleClick} โœ…
  • onClick={handleClick()} โŒ โ†’ ํ•จ์ˆ˜๊ฐ€ ์ฆ‰์‹œ ์‹คํ–‰๋จ
/* ์ปดํฌ๋„ŒํŠธ ์‚ฌ์ด์— text๋Š” props.children๋ฐ›์„์ˆ˜์žˆ๋‹ค. */
export default function TabButton({ children }) {
  function handleClick() {
    console.log("hellow world");
  }

  //({children})๊ฐ€๋Šฅ ์ปดํฌ๋„ŒํŠธ ์†์„ฑ์ธ label๋กœ ๋„˜๊ธฐ๋ฉด ({label}) ๊ฐ€๋Šฅ
  return (
    <li>
          {/* props์˜ ๋‚ด์žฅ๊ฐ์ฒด์ธ children ์ปดํฌ๋„ŒํŠธ ํƒœ๊ทธ ์‚ฌ์ด์— text๋ฅผ ๋ฐ›์•„์˜ด */}
          {/* ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ onClick ๋ฒ„ํŠผ ํด๋ฆญ์‹œ ์ด๋ฒคํŠธ ๋ฐœ์ƒ handleClick ํ•จ์ˆ˜ ํ˜ธ์ถœ */}
      <button onClick={handleClick}>{children}</button>
    </li>
  );
}

ํ•จ์ˆ˜๋ฅผ Prop(์†์„ฑ)์˜ ๊ฐ’์œผ๋กœ ์ „๋‹ฌํ•˜๊ธฐ

App ์ปดํฌ๋„ŒํŠธ์—์„œ onSelect prop์œผ๋กœ ํ•จ์ˆ˜๋ฅผ TabButton์— ์ „๋‹ฌ

// App.jsx
function handleSelect() {
  console.log("Selected!");
}
<TabButton onSelect={handleSelect}>Components</TabButton>

TabButton ์ปดํฌ๋„ŒํŠธ์—์„œ๋Š” onSelect๋ฅผ ๋ฐ›์•„ ๋‚ด๋ถ€ <button>์˜ onClick์— ์—ฐ๊ฒฐ

export default function TabButton({ children, onSelect }) {
  return <li><button onClick={onSelect}>{children}</button></li>;
}

์ด๋ฒคํŠธ ํ•จ์ˆ˜์— ์ปค์Šคํ…€ ์ธ์ž ์ „๋‹ฌํ•˜๊ธฐ

ํ™”์‚ดํ‘œ ํ•จ์ˆ˜ ์‚ฌ์šฉ

onSelect={handleSelect} ๋กœ ๋„˜๊ธฐ๋ฉด ๋ฆฌ์•กํŠธ๊ฐ€ ์–ด๋–ค ๊ฐ’์„ ์ „๋‹ฌํ•ด์•ผ ํ• ์ง€ ๋ชจ๋ฆ„ onClick ์ด๋ฒคํŠธ์— ์ธ์ž๊ฐ’์„ ์ „๋‹ฌํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด์•ผํ•จ

<TabButton onSelect={() => handleSelect('Components')}>Components</TabButton>
<TabButton onSelect={() => handleSelect('JSX')}>JSX</TabButton>
  • ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋Š” ์ง€๊ธˆ ์‹คํ–‰๋˜์ง€ ์•Š์œผ๋ฉฐ, ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ์—๋งŒ ์‹คํ–‰๋จ
  • ๋”ฐ๋ผ์„œ ๋‚ด๋ถ€์—์„œ handleSelect()๋ฅผ ํ˜ธ์ถœํ•˜๋ฉฐ ์›ํ•˜๋Š” ์ธ์ˆ˜ ์ „๋‹ฌ์ด ๊ฐ€๋Šฅ

State(์ƒํƒœ) ๊ด€๋ฆฌ & Hooks(ํ›…) ์‚ฌ์šฉ๋ฒ•

useState๋ž€?

  • ๋ฆฌ์•กํŠธ๊ฐ€ ์ œ๊ณตํ•˜๋Š” Hook ํ•จ์ˆ˜
  • ์ปดํฌ๋„ŒํŠธ์˜ ์ƒํƒœ(๋ฐ์ดํ„ฐ) ๋ฅผ ์ €์žฅํ•˜๊ณ  ๊ด€๋ฆฌํ•˜๋ฉฐ,
  • ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ž๋™์œผ๋กœ ๋‹ค์‹œ ์‹คํ–‰(๋ Œ๋”๋ง) ๋จ
import { useState } from 'react';

const [selectedTopic, setSelectedTopic] = useState('Please click a button');

selectedTopic : ํ˜„์žฌ ์ƒํƒœ ๊ฐ’ (์ดˆ๊ธฐ๊ฐ’์œผ๋กœ ์„ค์ •๋จ) setSelectedTopic : ์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋Š” ํ•จ์ˆ˜. ํ˜ธ์ถœ ์‹œ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์žฌ์‹คํ–‰๋จ

setSelectedTopic()์„ ์‚ฌ์šฉํ•˜์—ฌ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝ

function handleSelect(selectedButton) {
  setSelectedTopic(selectedButton);
  console.log(selectedTopic) //์ด์ „ ๊ฐ’์ด ์ถœ๋ ฅ
}
  • setSelectedTopic()์„ ํ˜ธ์ถœํ•˜๋ฉด ์ปดํฌ๋„ŒํŠธ ํ•จ์ˆ˜ ์ „์ฒด๊ฐ€ ๋‹ค์‹œ ์‹คํ–‰๋จ
  • ๊ทธ๋Ÿฌ๋‚˜ ์ƒํƒœ ์—…๋ฐ์ดํŠธ๋Š” ์ฆ‰์‹œ ๋ฐ˜์˜๋˜์ง€ ์•Š๊ณ  ๋น„๋™๊ธฐ์ ์œผ๋กœ ์˜ˆ์•ฝ๋จ
  • ๊ทธ ๊ฒฐ๊ณผ, setSelectedTopic() ๋ฐ”๋กœ ๋‹ค์Œ์— console.log(selectedTopic)์„ ์ฐ์œผ๋ฉด ์ด์ „ ๊ฐ’์ด ์ถœ๋ ฅ๋จ
  • ์กฐ๊ฑด๋ฌธ, ๋ฐ˜๋ณต๋ฌธ, ๋‚ด๋ถ€ ํ•จ์ˆ˜ ๋“ฑ์—์„œ๋Š” ํ˜ธ์ถœ ๋ถˆ๊ฐ€
  • ์ƒํƒœ ๋ณ€๊ฒฝ ํ•จ์ˆ˜๋Š” ํ•ญ์ƒ ๋น„๋™๊ธฐ์ ์œผ๋กœ ์ž‘๋™ํ•˜๋ฉฐ, ์ปดํฌ๋„ŒํŠธ๋ฅผ ์žฌ์‹คํ–‰์‹œํ‚ด
  • ์ƒํƒœ ๊ฐ’์€ ๋ณ€๊ฒฝ ๋ถˆ๊ฐ€ ์ƒ์ˆ˜๋กœ ์œ ์ง€ (const)
  • useState๋Š” ๋ฆฌ์•กํŠธ์—์„œ UI๋ฅผ ์ƒํƒœ ๊ธฐ๋ฐ˜์œผ๋กœ ๋™์ ์œผ๋กœ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ ํ•ต์‹ฌ ๋„๊ตฌ
  • ์ด๋ฒคํŠธ + ์ƒํƒœ + ์žฌ๋ Œ๋”๋ง์ด๋ผ๋Š” ํ๋ฆ„์„ ํ†ตํ•ด ๋™์ž‘

๋ฐ์ดํ„ฐ ๊ธฐ๋ฐ˜ State(์ƒํƒœ) ๊ฐ€์ ธ์˜ค๊ธฐ ๋ฐ ์ถœ๋ ฅ

์ƒํƒœ ์ดˆ๊ธฐํ™”

์ƒํƒœ ์ดˆ๊ธฐ๊ฐ’์€ components๋กœ ์„ค์ •

const [selectedTopic, setSelectedTopic] = useState("components");

handleSelect ํ•จ์ˆ˜ ๋‚ด์—์„œ ์ƒํƒœ ์—…๋ฐ์ดํŠธ

function handleSelect(selectedButton) {
  setSelectedTopic(selectedButton);
}

data.js์—์„œ EXAMPLES ๊ฐ์ฒด๋ฅผ import

import { EXAMPLES } from "./data.js";

JSX์—์„œ ์ƒํƒœ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋™์ ์œผ๋กœ ์ ‘๊ทผ selectedTopic ๊ฐ’์ด ๋ณ€ํ•จ์— ๋”ฐ๋ผ EXAMPLES ๊ฐ์ฒด๊ฐ’์ด ๋™์ ์œผ๋กœ ์ถœ๋ ฅ

<h3>{EXAMPLES[selectedTopic].title}</h3>
<p>{EXAMPLES[selectedTopic].description}</p>
<pre>
  <code>{EXAMPLES[selectedTopic].code}</code>
</pre>

์ดˆ๊ธฐ ์ƒํƒœ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ

  • ์ƒํƒœ ์ดˆ๊ธฐ๊ฐ’์ด components๋กœ ์„ค์ •๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ฒซ ํ™”๋ฉด ๋ Œ๋”๋ง ์‹œ ์˜ค๋ฅ˜ ์—†์Œ
  • ์ดˆ๊ธฐ ์ƒํƒœ๋กœ "Please click a button"๊ณผ ๊ฐ™์€ ์กด์žฌํ•˜์ง€ ์•Š๋Š” ํ‚ค๋ฅผ ๋„ฃ์œผ๋ฉด EXAMPLES[selectedTopic]๊ฐ€ undefined๊ฐ€ ๋˜์–ด ์˜ค๋ฅ˜ ๋ฐœ์ƒ

์กฐ๊ฑด์  ์ฝ˜ํ…์ธ  ๋ Œ๋”๋ง

๊ธฐ์กด์—๋Š” useState ์ดˆ๊ธฐ๊ฐ’์€ components๋กœ ์„ค์ •๋˜์–ด ์žˆ์–ด์„œ components ๊ด€๋ จ contents๊ฐ€ ์ถœ๋ ฅ ๋˜์—ˆ์ง€๋งŒ ์ดˆ๊ธฐํ™”๋ฉด์— โ€œPlease select a topicโ€ ํ…์ŠคํŠธ ์ถœ๋ ฅํ•˜๊ณ ์‹ถ๋‹ค๋ฉด

์ƒํƒœ ์ดˆ๊ธฐ๊ฐ’์„ ๋นˆ ๋ฌธ์ž์—ด๋กœ ์„ค์ •

const [selectedTopic, setSelectedTopic] = useState('');
  • ์•„๋ฌด ๋ฒ„ํŠผ๋„ ์„ ํƒ๋˜์ง€ ์•Š์•˜์Œ์„ ๋‚˜ํƒ€๋‚ด๊ธฐ ์œ„ํ•ด ๋นˆ ๋ฌธ์ž์—ด(โ€œโ€) ์‚ฌ์šฉ
  • EXAMPLES['']๋Š” ์กด์žฌํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์—, ์กฐ๊ฑด ์—†์ด ์ ‘๊ทผํ•˜๋ฉด ์˜ค๋ฅ˜ ๋ฐœ์ƒ

์กฐ๊ฑด๋ถ€ ๋ Œ๋”๋ง ๋ฐฉ์‹ 3๊ฐ€์ง€

์‚ผํ•ญ ์—ฐ์‚ฐ์ž ์‚ฌ์šฉ
{!selectedTopic 
  ? <p>Please select a topic</p> 
  : <div id="tab-content"> 
      <h3>{EXAMPLES[selectedTopic].title}</h3>
      <p>{EXAMPLES[selectedTopic].description}</p>
      <pre><code>{EXAMPLES[selectedTopic].code}</code></pre>
    
AND ์—ฐ์‚ฐ์ž (&&) ์‚ฌ์šฉ
{!selectedTopic && <p>Please select a topic</p>}
{selectedTopic && (
  <div id="tab-content">
    <h3>{EXAMPLES[selectedTopic].title}</h3>
    <p>{EXAMPLES[selectedTopic].description}</p>
    <pre><code>{EXAMPLES[selectedTopic].code}</code></pre>
  </div>
)}
๋ณ€์ˆ˜์— JSX ์ €์žฅ (if๋ฌธ ํ™œ์šฉ)
let tabContent = <p>Please select a topic</p>;

if (selectedTopic) {
  tabContent = (
    <div id="tab-content">
      <h3>{EXAMPLES[selectedTopic].title}</h3>
      <p>{EXAMPLES[selectedTopic].description}</p>
      <pre><code>{EXAMPLES[selectedTopic].code}</code></pre>
    </div>
  );
}

// JSX ๋‚ด์— ๋ณ€์ˆ˜ ์‚ฝ์ž…
{tabContent}

CSS ์Šคํƒ€์ผ๋ง ๋ฐ ๋™์  ์Šคํƒ€์ผ๋ง

  • ์‚ฌ์šฉ์ž๊ฐ€ ํด๋ฆญํ•œ ๋ฒ„ํŠผ(TabButton)์„ ์‹œ๊ฐ์ ์œผ๋กœ ๊ฐ•์กฐ(ํ™œ์„ฑํ™” ์Šคํƒ€์ผ ์ ์šฉ)
  • ์„ ํƒ๋œ ๋ฒ„ํŠผ์—๋งŒ active ํด๋ž˜์Šค๋ฅผ ๋™์ ์œผ๋กœ ์ถ”๊ฐ€

className์€ JSX์—์„œ ์Šคํƒ€์ผ๋ง์„ ์œ„ํ•œ ์†์„ฑ

  • HTML์˜ class์™€ ๊ฐ™์ง€๋งŒ, JSX์—์„œ๋Š” className์„ ์‚ฌ์šฉ
  • isSelected๊ฐ€ true์ด๋ฉด active ํด๋ž˜์Šค ์ ์šฉ
  • false์ด๋ฉด ํด๋ž˜์Šค ์—†์Œ
/* ์ปดํฌ๋„ŒํŠธ ์‚ฌ์ด์— text๋Š” props.children๋ฐ›์„์ˆ˜์žˆ๋‹ค. */
export default function TabButton({ children, onSelect, isSelected }) {
  //({children})๊ฐ€๋Šฅ ์ปดํฌ๋„ŒํŠธ ์†์„ฑ์ธ label๋กœ ๋„˜๊ธฐ๋ฉด ({label}) ๊ฐ€๋Šฅ
  return (
    <li>
      {/* props์˜ ๋‚ด์žฅ๊ฐ์ฒด์ธ children ์ปดํฌ๋„ŒํŠธ ํƒœ๊ทธ ์‚ฌ์ด์— text๋ฅผ ๋ฐ›์•„์˜ด */}
      {/* ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ onClick ๋ฒ„ํŠผ ํด๋ฆญ์‹œ ์ด๋ฒคํŠธ ๋ฐœ์ƒ handleClick ํ•จ์ˆ˜ ํ˜ธ์ถœ */}
      <button className={isSelected ? "active" : undefined} onClick={onSelect}>
        {children}
      </button>
    </li>
  );
}

App ์ปดํฌ๋„ŒํŠธ์—์„œ ์ƒํƒœ์— ๋”ฐ๋ผ isSelected ์ „๋‹ฌ

			<TabButton
              isSelected={selectedTopic === "components"}
              onSelect={() => handleSelect("components")}
            >
              Components
            </TabButton>
            <TabButton
              isSelected={selectedTopic === "jsx"}
              onSelect={() => handleSelect("jsx")}
            >
              JSX
            </TabButton>
            <TabButton
              isSelected={selectedTopic === "props"}
              onSelect={() => handleSelect("props")}
            >
              Props
            </TabButton>
            <TabButton
              isSelected={selectedTopic === "state"}
              onSelect={() => handleSelect("state")}
            >
              State
            </TabButton>
  • selectedTopic ์ƒํƒœ์™€ ํ˜„์žฌ ๋ฒ„ํŠผ์˜ ์‹๋ณ„์ž('components', 'jsx', 'props', 'state')๋ฅผ ๋น„๊ตํ•ด true/false ๊ฒฐ์ •
  • ์ด ๊ฐ’์ด TabButton์— isSelected๋กœ ์ „๋‹ฌ๋จ

List(๋ฆฌ์ŠคํŠธ) ๋ฐ์ดํ„ฐ ๋™์  ์ถœ๋ ฅ

๊ธฐ์กด์—๋Š” CoreConcept ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ˆ˜๋™์œผ๋กœ 4๋ฒˆ ์ถœ๋ ฅ๋˜๊ฒŒํ•จ ๋ฐ์ดํ„ฐ(CORE_CONCEPTS)๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด ์ˆ˜๋™์œผ๋กœ ์ฝ”๋“œ๋„ ์ˆ˜์ •ํ•ด์•ผ ํ•จ ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ค‘๋ณต ์ฝ”๋“œ๊ฐ€ ๋งŽ๊ณ , ์œ ์ง€๋ณด์ˆ˜์„ฑ์ด ๋‚ฎ์Œ

<CoreConcept {...CORE_CONCEPTS[0]} />
<CoreConcept {...CORE_CONCEPTS[1]} />
<CoreConcept {...CORE_CONCEPTS[2]} />
<CoreConcept {...CORE_CONCEPTS[3]} />

.map()์„ ํ™œ์šฉํ•œ ๋™์  ๋ Œ๋”๋ง

map() ์•ˆ์—์„œ JSX ์š”์†Œ๋ฅผ ๋ฐ˜ํ™˜ CORE_CONCEPTS ๋ฐฐ์—ด์˜ ํฌ๊ธฐ์— ๋งž๊ฒŒ ์ž๋™์œผ๋กœ ๋ Œ๋”๋ง๋จ ํ•ญ๋ชฉ์ด ์ถ”๊ฐ€/์ œ๊ฑฐ๋˜๋ฉด ์ฝ”๋“œ ์ˆ˜์ • ์—†์ด ์ž๋™ ๋ฐ˜์˜

{CORE_CONCEPTS.map((item) => (
    <CoreConcept key={item.title} {...item} />
))}
  • ๋ฆฌ์•กํŠธ๊ฐ€ ํ•ญ๋ชฉ์„ ๊ณ ์œ ํ•˜๊ฒŒ ์‹๋ณ„ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•จ
  • ํšจ์œจ์ ์ธ ๋ฆฌ๋ Œ๋”๋ง ๋ฐ DOM ์—…๋ฐ์ดํŠธ๋ฅผ ์œ„ํ•ด ์‚ฌ์šฉ๋จ
  • ๋ฐ˜๋ณต ์ปดํฌ๋„ŒํŠธ์—๋Š” ๋ฐ˜๋“œ์‹œ ๊ณ ์œ ํ•œ key ๊ฐ’์ด ํ•„์š”
  • ์˜ˆ์‹œ: title, id, ํ˜น์€ ๊ณ ์œ ํ•œ ์‹๋ณ„์ž ์‚ฌ์šฉ

๐Ÿ“‘ Reference



Pagination


ยฉ 2025. All rights reserved.

Powered by Hydejack v9.2.1