๐ [Recat] React ํต์ฌ - ์ปดํฌ๋ํธ, JSX, ์์ฑ, ์ํ ๋ฑ - 1
![๐ [Recat] React ํต์ฌ - ์ปดํฌ๋ํธ, JSX, ์์ฑ, ์ํ ๋ฑ - 1](/assets/img/thumbnail/react-thumbnail.jpg)
[Recat] React ํต์ฌ - ์ปดํฌ๋ํธ, JSX, ์์ฑ, ์ํ ๋ฑ - 1
์ ์ปดํฌ๋ํธ๊ฐ ์ค์ํ๊ฐ?
- UI ๊ตฌ์กฐํ: ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฒด๋ฅผ ์ปดํฌ๋ํธ ๋จ์๋ก ๋๋์ด ๊ตฌ์กฐํํฉ๋๋ค.
- ์ฌ์ฌ์ฉ์ฑ: ํ ๋ฒ ๋ง๋ ์ปดํฌ๋ํธ๋ฅผ ์ฌ๋ฌ ๊ณณ์์ ์ฌ์ฌ์ฉํ ์ ์์ต๋๋ค.
- ์ ์ง๋ณด์ ์ฉ์ด: ์์ ์ด ํ์ํ ๊ฒฝ์ฐ, ์ปดํฌ๋ํธ ๋ด๋ถ๋ง ๋ณ๊ฒฝํ๋ฉด ๋ฉ๋๋ค.
- ๊ด์ฌ์ฌ์ ๋ถ๋ฆฌ: ๊ฐ ์ปดํฌ๋ํธ๋ ์์ ์ ์ญํ ๋ง ๋ด๋นํ๊ธฐ ๋๋ฌธ์ ์ฝ๋๊ฐ ๋ช ํํด์ง๋๋ค.
- ํ์ ์ ์ ๋ฆฌ: ์ฌ๋ฌ ๊ฐ๋ฐ์๊ฐ ๊ฐ์์ ์ปดํฌ๋ํธ๋ฅผ ๋ด๋นํด ๊ฐ๋ฐํ ์ ์์ต๋๋ค.
์ปดํฌ๋ํธ ๊ธฐ๋ฐ ์ ๊ทผ์ ์ฅ์
- ์ฝ๋ ์ค๋ณต ๊ฐ์ ๋ฐ ์์ ์ฉ์ด
- ๊ด๋ จ ์ฝ๋(HTML, CSS, JS)์ ํจ๊ป ๊ด๋ฆฌ
- ๋์์ธ๊ณผ ๊ธฐ๋ฅ์ ๋ช ํํ ๋ถ๋ฆฌ
- ์ฑ ๊ท๋ชจ๊ฐ ์ปค์ ธ๋ ํจ์จ์ ์ธ ๊ฐ๋ฐ ๊ฐ๋ฅ
๋ฆฌ์กํธ ์ธ ๋ค๋ฅธ ํ๋ ์์ํฌ๋ ์ฌ์ฉ
์ด๋ฌํ ์ปดํฌ๋ํธ ์ค์ฌ ๊ฐ๋ฐ ๋ฐฉ์์ ๋ฆฌ์กํธ์๋ง ๊ตญํ๋์ง ์๊ณ , Vue, Angular, Svelte, ์ฌ์ง์ด๋ Flutter์ ๊ฐ์ ๋ชจ๋ฐ์ผ ํ๋ ์์ํฌ์์๋ ์ฌ์ฉ๋ฉ๋๋ค.
๋ฆฌ์กํธ์ ์ฒซ๊ฑธ์: ํ๋ก์ ํธ ๊ตฌ์กฐ์ JSX, ๊ทธ๋ฆฌ๊ณ ์ปดํฌ๋ํธ ๋ง๋ค๊ธฐ
๋ฆฌ์กํธ ํ๋ก์ ํธ๋ฅผ ์ฒ์ ์คํํ๋ฉด ๊ธฐ๋ณธ์ ์ผ๋ก ๋ค์ํ ํ์ผ๊ณผ ํด๋๊ฐ ์์ฑ๋ฉ๋๋ค. ๊ทธ์ค public/index.html
ํ์ผ์ ๊ธฐ๋ณธ์ ์ธ HTML ๋งํฌ์
๋ง ํฌํจํ๊ณ ์์ผ๋ฉฐ, ์ฐ๋ฆฌ๊ฐ ์ค์ ๋ก ํ๋ฉด์์ ๋ณด๋ UI ์์๋ ์ด๊ณณ์ ์์ต๋๋ค. ์ด์ ๋ ๋ฐ๋ก ํ๋ฉด์ ๋ณด์ด๋ ๋ชจ๋ UI๊ฐ ๋ฆฌ์กํธ๋ฅผ ํตํด ์์ฑ๋๊ธฐ ๋๋ฌธ์
๋๋ค.
index.html
๊ณผ ๋ฆฌ์กํธ์ ์ฐ๊ฒฐ ๊ณ ๋ฆฌ
index.html
์๋ ๋ฆฌ์กํธ ์ฑ์ด ์ฝ์ ๋ root DOM ์์๊ฐ ์์ต๋๋ค.- ์ค์ ์ฝํ ์ธ ๋ ์๋ฐ์คํฌ๋ฆฝํธ ํ์ผ์ ํตํด ๋์ ์ผ๋ก ๋ ๋๋ง๋ฉ๋๋ค.
index.jsx
ํ์ผ์์ ์ฑ์ ์์์ ์ ์ ์ํ๊ณ ์์ผ๋ฉฐ, ๊ทธ ์์์App.jsx
์ปดํฌ๋ํธ๋ฅผ ๋ถ๋ฌ์ต๋๋ค.
JSX๋ ๋ฌด์์ธ๊ฐ?
App.jsx
ํ์ผ์ ๋ณด๋ฉด ์๋ฐ์คํฌ๋ฆฝํธ ์ฝ๋ ์์ HTML์ฒ๋ผ ๋ณด์ด๋ ๋ฌธ๋ฒ์ด ์์ต๋๋ค. ์ด๊ฒ์ด ๋ฐ๋ก JSX (JavaScript Syntax Extension) ์ ๋๋ค.- JSX๋ฅผ ์ฌ์ฉํ๋ฉด ์๋ฐ์คํฌ๋ฆฝํธ ํ์ผ ๋ด์ HTML ๋งํฌ์ ์ ์ง์ ์์ฑํ ์ ์์ด UI ๊ตฌ์ฑ์ ๋งค์ฐ ์ ์ฉํฉ๋๋ค.
- ๋จ, JSX๋ ๋ธ๋ผ์ฐ์ ๊ฐ ์ดํดํ ์ ์๋ ๋ฌธ๋ฒ์ด๋ฏ๋ก, ๊ฐ๋ฐ ์๋ฒ๊ฐ ๋ธ๋ผ์ฐ์ ๊ฐ ์ดํดํ ์ ์๋ ์ฝ๋๋ก ๋ณํ(ํธ๋์คํ์ผ) ํด์ค๋๋ค.
๋ฆฌ์กํธ ์ปดํฌ๋ํธ์ ๊ธฐ๋ณธ
App.jsx
๋ ํ๋์ ์ปดํฌ๋ํธ์ ๋๋ค. ์ปดํฌ๋ํธ๋ ๋ฆฌ์กํธ์์ UI๋ฅผ ๊ตฌ์ฑํ๋ ํต์ฌ ๋จ์์ ๋๋ค.- ๋ฆฌ์กํธ ์ปดํฌ๋ํธ๋ ์๋ฐ์คํฌ๋ฆฝํธ ํจ์์ฒ๋ผ ์์ฑ๋๋ฉฐ, ๋ค์ ๋ ๊ฐ์ง ๊ท์น์ ๋ฐ๋ผ์ผ ํฉ๋๋ค:
- ํจ์ ์ด๋ฆ์ ๋๋ฌธ์๋ก ์์ํด์ผ ํฉ๋๋ค.
- ๋ ๋๋ง ๊ฐ๋ฅํ JSX๋ฅผ ๋ฐํํด์ผ ํฉ๋๋ค.
๋ฆฌ์กํธ ์ปดํฌ๋ํธ ์์ฑ๊ณผ ์ฌ์ฉ์ ์ฒซ๊ฑธ์
๋ฆฌ์กํธ ์ปดํฌ๋ํธ๋ ๋จ์ํ ์๋ฐ์คํฌ๋ฆฝํธ ํจ์์ ๋๋ค. ๋ฐ๋ผ์ ์ผ๋ฐ ํจ์์ฒ๋ผ ์ ์ธํ ์ ์์ง๋ง, ๋ค์ ๋ ๊ฐ์ง ๊ท์น์ ๋ฐ๋ผ์ผ ํฉ๋๋ค:
- ํจ์ ์ด๋ฆ์ ๋๋ฌธ์๋ก ์์ํด์ผ ํฉ๋๋ค.
- JSX๋ฅผ ๋ฐํํด์ผ ํฉ๋๋ค. (์ฆ, ํ๋ฉด์ ๋ ๋๋ง๋ ๋งํฌ์ )
์ปดํฌ๋ํธ ๋ง๋ค๊ธฐ
์๋ฅผ ๋ค์ด, ๊ธฐ์กด App
์ปดํฌ๋ํธ์ ์๋ ํค๋ ๋งํฌ์
์ ๋ถ๋ฆฌํด Header
์ปดํฌ๋ํธ๋ฅผ ์์ฑํ ์ ์์ต๋๋ค.
function Header() {
return (
<header>
<img src="src/assets/react-core-concepts.png" alt="Stylized atom" />
<h1>React Essentials</h1>
<p>
Fundamental React concepts you will need for almost any app you are going to build!
</p>
</header>
);
}
์ปดํฌ๋ํธ ์ฌ์ฉํ๊ธฐ
๋ง๋ ์ปดํฌ๋ํธ๋ JSX ๋ฌธ๋ฒ ์์์ HTML ํ๊ทธ์ฒ๋ผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
function App() {
return (
<div>
<Header />
<main>
<h2>Time to get started!</h2>
</main>
</div>
);
}
- ์ปดํฌ๋ํธ ํ๊ทธ๋ ๋ฐ๋์ ์ฌ๋์(/) ๋ฅผ ํฌํจํ ์๋ ๋ซํ ๋ฌธ๋ฒ ๋๋ ์์/์ข ๋ฃ ํ๊ทธ๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
- JSX๋ ๋ธ๋ผ์ฐ์ ๊ฐ ์ง์ ์ดํดํ์ง ๋ชปํ๋ฏ๋ก, ๊ฐ๋ฐ ์๋ฒ์์ ์ผ๋ฐ ์๋ฐ์คํฌ๋ฆฝํธ๋ก ๋ณํ๋์ด ์คํ๋ฉ๋๋ค.
๐ก ๋ฆฌ์กํธ ์ปดํฌ๋ํธ๊ฐ ์ค์ ๋ก ํ๋ฉด์ ๋ ๋๋ง๋๋ ๊ณผ์
1. ์ปดํฌ๋ํธ๋ ์ค์ HTML์ ๋ณด์ด์ง ์๋๋ค
- ๋ธ๋ผ์ฐ์ ์์ ํ์ด์ง ์์ค๋ฅผ ๋ณด๋ฉด
Header
๋App
๊ฐ์ ์ปค์คํ ์ปดํฌ๋ํธ๋ ๋ณด์ด์ง ์์ต๋๋ค. - ๋์
<div id="root">
์ ๋ฆฌ์กํธ๊ฐ ์ต์ข ์ ์ผ๋ก ๋ณํํ ๋ด์ฅ HTML ์์๋ค๋ง ์์ต๋๋ค.
2. JSX๋ ๋ธ๋ผ์ฐ์ ์์ ์ง์ ์คํ๋์ง ์๋๋ค
- JSX๋ ๋ธ๋ผ์ฐ์ ๊ฐ ์ดํดํ์ง ๋ชปํ๊ธฐ ๋๋ฌธ์ ๊ฐ๋ฐ ์๋ฒ์์ ๋ณํ๋์ด ์ผ๋ฐ ์๋ฐ์คํฌ๋ฆฝํธ๋ก ๋ฐ๋๋๋ค.
- ์ด ์์
์
index.jsx
์์ ์ํ๋ฉ๋๋ค.
3. index.jsx๊ฐ ๋ฆฌ์กํธ ์ฑ์ ์ง์ ์
index.html
์ ๊ธฐ๋ณธ์ ์ธ HTML ๊ตฌ์กฐ๋ง ํฌํจํ๊ณ ์๊ณ ,<div id="root">
๊ฐ ํต์ฌ์ ๋๋ค.index.jsx
์์App
์ปดํฌ๋ํธ๋ฅผ ๊ฐ์ ธ์createRoot().render(<App />)
๋ฅผ ํตํด ํด๋น div์ ๋ ๋๋งํฉ๋๋ค.
4. ๋ฆฌ์กํธ๊ฐ ๋ ๋๋งํ๋ ๋ฐฉ์
createRoot()
๋ ๋ฆฌ์กํธ ์ฑ์ ๊ธฐ์กด DOM ์์ ์์ ์ฝ์ ํ ์ ์๋๋ก ๋ง๋ญ๋๋ค.render()
๋ ์ฐ๋ฆฌ๊ฐ ๋ง๋ ์ปดํฌ๋ํธ๋ฅผ ์ค์ HTML ์์๋ก ๋ณํํ์ฌ<div id="root">
์์ ์ฝ์ ํฉ๋๋ค.
5. ์ปดํฌ๋ํธ ํธ๋ฆฌ (Component Tree)
App
โHeader
์ฒ๋ผ ์ปดํฌ๋ํธ๋ ์ค์ฒฉ๋์ด ํธ๋ฆฌ ๊ตฌ์กฐ๋ฅผ ํ์ฑํฉ๋๋ค.- ๋ฆฌ์กํธ๋ ์ด ์ปดํฌ๋ํธ ํธ๋ฆฌ๋ฅผ ๋ถ์ํด์ ์ต์ข HTML ๊ตฌ์กฐ๋ฅผ ๋ง๋ญ๋๋ค.
6. ์ ์ปดํฌ๋ํธ ์ด๋ฆ์ ๋๋ฌธ์๋ก ์์ํด์ผ ํ๋์?
- ์๋ฌธ์๋ก ์์ํ๋ฉด ๋ฆฌ์กํธ๋ ์ด๋ฅผ ๊ธฐ๋ณธ HTML ํ๊ทธ๋ก ์คํดํฉ๋๋ค.
- ๋๋ฌธ์๋ก ์์ํ๋ฉด ์ฌ์ฉ์ ์ ์ ์ปดํฌ๋ํธ๋ก ์ธ์ํฉ๋๋ค.
- ์ด๋ ๋ด์ฅ ์์์ ์ปค์คํ ์์ ๊ฐ์ ์ด๋ฆ ์ถฉ๋ ๋ฐฉ์ง๋ฅผ ์ํ ๊ท์น์ ๋๋ค.
๋์ ๊ฐ ์ถ๋ ฅ ๋ฐ ํ์ฉ
JSX๋ HTML์ฒ๋ผ ๋ณด์ด์ง๋ง, ์ค๊ดํธ {}
๋ฅผ ์ฌ์ฉํด ์๋ฐ์คํฌ๋ฆฝํธ ํํ์์ ์ฝ์
ํ ์ ์์
//reactDescriptions ๋ฐฐ์ด์์ ๋๋ค์ผ๋ก ํ๋์ ๋จ์ด๋ฅผ ์ ํํ๊ธฐ ์ํ ์ค๋น
const reactDescriptions = ['Fundamental', 'Crucial', 'Core'];
function genRandomInt(max) { //genRandomInt(2)`๋ 0, 1, 2 ์ค ๋ฌด์์ ์ ์ ๋ฐํ
return Math.floor(Math.random() * (max + 1));
}
//Header ์ปดํฌ๋ํธ ๋ด ๋์ ํํ ์ ์ฉ
function Header() {
// ๋ณ์๋ก ํ์ฉ description์ผ๋ก ์ง์ ํ์ฌ return๊ฐ์ ์ฌ์ฉํ๋ค. javascript ํํ์ ์ฝ๋ ๋ฐ์ผ๋ก ์ฎ๊ธฐ๋ฉด jsx์ฝ๋๊ฐ ์กฐ๊ธ ๊น๋ํด ์ง ์ ์๋ค.
const description = reactDescriptions[genRandomInt(2)]
return (
<header>
<img src="src/assets/react-core-concepts.png" alt="Stylized atom" />
<h1>React Essentials</h1>
<p>
{/*reactDescriptions[genRandomInt(2)]}*/}
{description} React concepts you will need for almost any app you are going to build!
</p>
</header>
);
}
function App() {
return (
<div>
<Header />
<main>
<h2>Time to get started!</h2>
</main>
</div>
);
}
๋์ HTML Attributes(์์ฑ) ์ค์ & ์ด๋ฏธ์ง ํ์ผ ๋ก๋ฉ
// ์ด๋ฏธ์ง ํ์ผ์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ importํ์ฌ ์ฌ์ฉํ๋ ๊ฒ์ ๊ถ์ฅ
import reactImg from './assets/react-core-concepts.png'
//reactDescriptions ๋ฐฐ์ด์์ ๋๋ค์ผ๋ก ํ๋์ ๋จ์ด๋ฅผ ์ ํํ๊ธฐ ์ํ ์ค๋น
const reactDescriptions = ['Fundamental', 'Crucial', 'Core'];
function genRandomInt(max) { //genRandomInt(2)`๋ 0, 1, 2 ์ค ๋ฌด์์ ์ ์ ๋ฐํ
return Math.floor(Math.random() * (max + 1));
}
//Header ์ปดํฌ๋ํธ ๋ด ๋์ ํํ ์ ์ฉ
function Header() {
// ๋ณ์๋ก ํ์ฉ description์ผ๋ก ์ง์ ํ์ฌ return๊ฐ์ ์ฌ์ฉํ๋ค. javascript ํํ์ ์ฝ๋ ๋ฐ์ผ๋ก ์ฎ๊ธฐ๋ฉด jsx์ฝ๋๊ฐ ์กฐ๊ธ ๊น๋ํด ์ง ์ ์๋ค.
const description = reactDescriptions[genRandomInt(2)]
return (
<header>
{/* <img src="src/assets/react-core-concepts.png" alt="..." /> */}
{/* src์์ฑ์ ๊ฒฝ๋ก ์ง์ ์
๋ ฅ์ ๋น์ถ์ฒ ๋ฐฐํฌ ์ ์ด๋ฏธ์ง๊ฐ ์ฌ๋ผ์ง ์ ์์ผ๋ฉฐ, ์ต์ ํ์ ๋ถ๋ฆฌํจ */}
<img src={reactImg} alt="Stylized atom" />
<h1>React Essentials</h1>
<p>
{/* ๋์ import ๋ฌธ์ผ๋ก ์ด๋ฏธ์ง ํ์ผ์ JS ๋ณ์๋ก ๋ถ๋ฌ์ค๊ณ , JSX์์ ์ค๊ดํธ ๋ฌธ๋ฒ์ผ๋ก ์ฐธ์กฐํจ */}
{/* ์ด ๋ฐฉ์์ ๋น๋ ๋๊ตฌ๊ฐ ์ด๋ฏธ์ง ํ์ผ๊น์ง ์๋์ผ๋ก ๋ฒ๋ค๋งํด ๋ฐฐํฌ์ ์ ํฉ */}
{description} React concepts you will need for almost any app you are going to build!
</p>
</header>
);
}
function App() {
return (
<div>
<Header />
<main>
<h2>Time to get started!</h2>
</main>
</div>
);
}
Prop(์์ฑ)์ผ๋ก ์ปดํฌ๋ํธ ์ฌ์ฌ์ฉ
1. ์ปดํฌ๋ํธ์ ์ฌ์ฌ์ฉ ๊ฐ๋ฅ์ฑ
- ๋ฆฌ์กํธ ์ปดํฌ๋ํธ๋ ์ฌ์ฌ์ฉ์ ๋ชฉ์ ์ผ๋ก ์ค๊ณ๋จ.
- ํ ๋ฒ ๋ง๋ ์ปดํฌ๋ํธ๋ฅผ ์ฌ๋ฌ ๋ฒ ํ์ฉํ ์ ์์.
- ๋จ, ๊ฐ ์ปดํฌ๋ํธ๋ ๋ค๋ฅธ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ง๊ณ ๋์ํด์ผ ์ ์๋ฏธํจ.
2. Props๋?
props
๋ ์ปดํฌ๋ํธ์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๊ธฐ ์ํ ๋ฉ์ปค๋์ฆ.- HTML ์์์ ์์ฑ์ฒ๋ผ ์ฌ์ฉ์ ์ ์ ์์ฑ์ ์ถ๊ฐ ๊ฐ๋ฅ.
<CoreConcept
title="Components"
description="The core UI building blocks"
image={componentsImg}
/>
- props๋ ๋ฆฌ์กํธ๊ฐ ์๋์ผ๋ก ์ปดํฌ๋ํธ ํจ์์ ๊ฐ์ฒด ํํ๋ก ์ ๋ฌ
function CoreConcept(props) {
return (
<li>
<img src={props.image} alt={props.title} />
<h3>{props.title}</h3>
<p>{props.description}</p>
</li>
);
}
๋ ๋ค์ํ Prop(์์ฑ) ๋ฌธ๋ฒ
1. data.js
๋ชจ๋ ๋์
CORE_CONCEPTS
๋ 4๊ฐ์ ๊ฐ๋ ์ ๋ด์ ๋ฐฐ์ด์ด๋ฉฐ, ๊ฐ ์์๋ ๋ค์ ์ ๋ณด๋ฅผ ํฌํจ:image
: ์ด๋ฏธ์ง ๊ฒฝ๋กtitle
: ์ ๋ชฉdescription
: ์ค๋ช
import componentsImg from "./assets/components.png";
import propsImg from "./assets/config.png";
import jsxImg from "./assets/jsx-ui.png";
import stateImg from "./assets/state-mgmt.png";
// CORE_CONCEPTS ๋ณ์๋ export๋ฅผ ์ฌ์ฉํ๋ฉด ๋ค๋ฅธ ์ปดํฌ๋ํธ์์ importํด์ ์ฌ์ฉํ ์ ์์
export const CORE_CONCEPTS = [
{
image: componentsImg,
title: "Components",
description:
"The core UI building block - compose the user interface by combining multiple components.",
},
{
image: jsxImg,
title: "JSX",
description:
"Return (potentially dynamic) HTML(ish) code to define the actual markup that will be rendered.",
},
{
image: propsImg,
title: "Props",
description:
"Make components configurable (and therefore reusable) by passing input data to them.",
},
{
image: stateImg,
title: "State",
description:
"React-managed data which, when changed, causes the component to re-render & the UI to update.",
},
];
2. ์ปดํฌ๋ํธ์ props๋ก ๋ฐ์ดํฐ ์ ๋ฌ
CoreConcept
์ปดํฌ๋ํธ๋ฅผ ํ๋ ๋ง๋ค๊ณ , ์ฌ๋ฌ ๋ฒ ์ฌ์ฉํ๋ฉด์ ๊ฐ๊ธฐ ๋ค๋ฅธ ๋ฐ์ดํฐ๋ฅผ props๋ก ์ ๋ฌ
import { CORE_CONCEPTS } from './data.js';
function CoreConcept(props) {
return (
<li>
<img src={props.image} alt={props.title} />
<h3>{props.title}</h3>
<p>{props.description}</p>
</li>
);
}
<CoreConcept
title={CORE_CONCEPTS[0].title}
description={CORE_CONCEPTS[0].description}
image={CORE_CONCEPTS[0].image}
/>
3. ์ฝ๋ ์ต์ ํ ๋ฐฉ๋ฒ: ์คํ๋ ๋ ์ฐ์ฐ์ ์ฌ์ฉ
- props์ ๊ฐ์ฒด ํค๊ฐ ๋์ผํ ๊ฒฝ์ฐ, ์คํ๋ ๋ ๋ฌธ๋ฒ์ผ๋ก ๊ฐ๊ฒฐํ๊ฒ ์์ฑ ๊ฐ๋ฅ
<CoreConcept {...CORE_CONCEPTS[0]} />
4. ์ปดํฌ๋ํธ ๋ด๋ถ ์ต์ ํ: ๊ตฌ์กฐ ๋ถํด ํ ๋น
props.title
๋ฐฉ์ ๋์ , ๊ตฌ์กฐ ๋ถํด ํ ๋น์ผ๋ก props๋ฅผ ๊ฐ๋จํ ๋ถ๋ฆฌํ ์ ์์
function CoreConcept({ title, description, image }) {
return (
<li>
<img src={image} alt={title} />
<h3>{title}</h3>
<p>{description}</p>
</li>
);
}
- ํ๋์
CoreConcept
์ปดํฌ๋ํธ๋ฅผ ๋ง๋ค๊ณ , 4๊ฐ์ง ๋ฐ์ดํฐ๋ฅผ ๋ฃ์ด ๋ฐ๋ณต์ ์ผ๋ก ์ฌ์ฌ์ฉ - JSX ๊ตฌ์กฐ์ ์ฝ๋์ ๊ฐ๋ ์ฑ๊ณผ ์ ์ง๋ณด์์ฑ ํฅ์
- ๋ถํ์ํ ๋ฐ๋ณต ์ ๊ฑฐ, ์ฝ๋ ๊ฐ๊ฒฐํ ๋ฌ์ฑ
๐ Reference
- ใํ๊ธ์๋งใ React ์๋ฒฝ ๊ฐ์ด๋ 2025 with React Router & Redux | Udemy
- ์ด๋ฏธ์ง ์ถ์ Freepik | ์ฌ์ธ์ AI ํฌ๋ฆฌ์์ดํฐ๋ธ ํด