An open API service indexing awesome lists of open source software.

https://github.com/ssi02014/create-compare-react

๐Ÿ™„ vanilla js ์™€ ๋น„๊ตํ•˜๋ฉฐ ํ•™์Šตํ•˜๋Š” react
https://github.com/ssi02014/create-compare-react

javascript react vanilla-javascript

Last synced: 8 months ago
JSON representation

๐Ÿ™„ vanilla js ์™€ ๋น„๊ตํ•˜๋ฉฐ ํ•™์Šตํ•˜๋Š” react

Awesome Lists containing this project

README

          

# ๐Ÿ’ป ๋งŒ๋“ค๊ณ  ๋น„๊ตํ•˜๋ฉฐ ํ•™์Šตํ•˜๋Š” ๋ฆฌ์•กํŠธ

## ๐Ÿ“– ch-1 Vanilla Javascript

- MVC ํŒจํ„ด์œผ๋กœ ๊ฒ€์ƒ‰ํผ ๊ตฌํ˜„ํ•˜๊ธฐ


### ๐Ÿ“„ lite-server ์‹คํ–‰ ๋ช…๋ น์–ด

```
npx lite-server --baseDir vanilla
npx lite-server --baseDir react
```


### ๐Ÿ™„ MVC๋ž€?

```
Model, View, Controller์˜ ์•ฝ์ž. ์†Œํ”„ํŠธ์›จ์–ด ๋””์ž์ธ ํŒจํ„ด์˜ ํ•˜๋‚˜๋กœ, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๊ธฐ๋Šฅ์„ ๊ตฌ๋ถ„ํ•จ์œผ๋กœ, ์ •๋ˆ๋œ ๊ฐœ๋ฐœ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•œ๋‹ค
```

1. Model
- `๋ฐ์ดํ„ฐ` ๋ฐ `๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง`์„ ๋‹ด๋‹นํ•œ๋‹ค.
- ๋ชจ๋ธ์€ `๋ฐ์ดํ„ฐ๋งŒ ๊ด€๋ฆฌ`ํ•œ๋‹ค. ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฐ์ดํ„ฐ์™€ ํ™”๋ฉด ์ถœ๋ ฅ์„ ์œ„ํ•œ ์ƒํƒœ๋ฅผ ๋‹ค๋ฃฌ๋‹ค.
- ex) DB์™€ ํ†ต์‹ ํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•œ๋‹ค, ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€๊ณตํ•˜์—ฌ ์ฒ˜๋ฆฌํ•œ๋‹ค ๋“ฑ
2. View
- `ํ™”๋ฉด`์„ ๋‹ด๋‹นํ•œ๋‹ค. (์‚ฌ์šฉ์ž์—๊ฒŒ ์–ด๋–ค ํ™”๋ฉด์„ ๋ณด์—ฌ์ฃผ๋ฉด ๋˜๋Š”์ง€)
- ๋ทฐ๋Š” ์™ธ๋ถ€์—์„œ ๋ฐ์ดํ„ฐ๊ฐ€ ๋“ค์–ด์˜จ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๊ณ  ํ™”๋ฉด์„ ๊ทธ๋ฆฐ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ž์‹ ์˜ ์—ญํ• ์ด ์•„๋‹ˆ๋ผ๊ณ  ํŒ๋‹จ๋˜๋ฉด `์ปค์Šคํ…€ ์ด๋ฒคํŠธ`๋กœ ์™ธ๋ถ€์— ์ด๋ฅผ ์•Œ๋ฆฐ๋‹ค.
3. Controller
- ์š”์ฒญ์„ ๋ฐ›์•„ Model๊ณผ View ์‚ฌ์ด์— `๋‹ค๋ฆฌ ์—ญํ• `์„ ํ•œ๋‹ค.
- ๋ชจ๋ธ๊ณผ ๋ทฐ๋ฅผ ์‚ฌ์šฉํ•ด ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋Œ์•„๊ฐ€๊ฒŒ๋” ํ•˜๋Š” ๊ฒƒ์ด ์ปจํŠธ๋กค๋Ÿฌ์˜ ์—ญํ• ์ด๋‹ค.
- `๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€๊ฒฝ`ํ•˜๊ณ  ์ด๋ฅผ `๋ทฐ์— ๋ฐ˜์˜`ํ•ด ํ™”๋ฉด์„ ๋ Œ๋”๋งํ•œ๋‹ค.
- ๋ฐ˜๋Œ€๋กœ ๋ทฐ์—์„œ ์‚ฌ์šฉ์ž ์ž…๋ ฅ์ด ๋ฐœ์ƒํ•˜๋ฉด ์ด๋ฅผ ๋ชจ๋ธ์— ์ €์žฅํ•ด์„œ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•œ๋‹ค.

- ๊ตฌ๋ถ„๋œ ์—ญํ• ๋กœ ์ธํ•ด ์—ญํ• (์ฑ…์ž„)์ด ๋ช…ํ™•ํ•ด์ง€๊ณ  ์œ ์ง€ ๋ณด์ˆ˜์˜ ์ด์ ์ด ์žˆ๋‹ค.
- ์œ ์—ฐํ•˜๊ณ  ํ™•์žฅ์„ฑ์ด ์ข‹๋‹ค.
- ๋‹จ์ ์œผ๋กœ๋Š” ์„ค๊ณ„ ์‹œ ๋งŽ์€ ์‹œ๊ฐ„ ๋ฐ ๋น„์šฉ์ด ์†Œ๋น„๋  ์ˆ˜ ์žˆ๋‹ค.


### ๐Ÿ™„ Javascript CustomEvent(), dispatchEvent()

- CustomEvent: ์ƒ์„ฑ์ž๋Š” ์ƒˆ๋กœ์šด `CustomEvent`๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
- dispatchEvent: ์ด๋ฒคํŠธ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ ๋‹ค์Œ `dispatchEvent(event)`๋ฅผ ํ˜ธ์ถœํ•ด ์š”์†Œ์— ์žˆ๋Š” ์ด๋ฒคํŠธ๋ฅผ ์‹คํ–‰์‹œํ‚จ๋‹ค.

```js
// CustomEvent ๊ธฐ๋ณธ ๊ตฌ๋ฌธ
CustomEvent(typeArg);
CustomEvent(typeArg, options);
```

- ๋งค๊ฐœ๋ณ€์ˆ˜

- typeArg: ์ด๋ฒคํŠธ์˜ ์ด๋ฆ„์„ ๋‚˜ํƒ€๋‚ด๋Š” ๋ฌธ์ž์—ด
- options(Optional): ๋‹ค์Œ ์†์„ฑ์„ ํฌํ•จํ•˜๋Š” ๊ฐ์ฒด

- ์˜ˆ์ œ

```js
// CustomEvent ์ƒ์„ฑ
const catFound = new CustomEvent("animalfound", {
detail: {
name: "cat",
},
});
const dogFound = new CustomEvent("animalfound", {
detail: {
name: "dog",
},
});

obj.addEventListener("animalfound", (e) => console.log(e.detail.name));

// ์ด๋ฒคํŠธ ๋ฐœ์†ก
obj.dispatchEvent(catFound);
obj.dispatchEvent(dogFound);

// ์ฝ˜์†”์— "cat"๊ณผ "dog"๊ฐ€ ๊ธฐ๋ก๋จ
```


## ๐Ÿ“– ch-2 React ์†Œ๊ฐœ

### ๐Ÿ™„ React

- DOM์— ์—˜๋ฆฌ๋จผํŠธ๊ฐ€ ์žˆ๋“ฏ์ด ๋ฆฌ์•กํŠธ ์•ฑ์—๋„ `์—˜๋ฆฌ๋จผํŠธ(Element)`๋ผ๋Š” ๊ฐœ๋…์ด ์žˆ๊ณ  ์ด๊ฒƒ์€ ๋ฆฌ์•กํŠธ ์•ฑ์„ ๊ตฌ์„ฑํ•˜๋Š” ์ตœ์†Œ ๋‹จ์œ„๋‹ค.
- ์›์ž๊ฐ€ ๋ชจ์—ฌ ๋ฌผ์งˆ์„ ์ด๋ฃจ๋“ฏ ๋ฆฌ์•กํŠธ ์—˜๋ฆฌ๋จผํŠธ ์—ฌ๋Ÿฌ๊ฐœ๋ฅผ ๋ชจ์•„ ๋ฆฌ์•กํŠธ ์•ฑ์„ ๋งŒ๋“ ๋‹ค. ๋ฆฌ์•กํŠธ ์—˜๋ฆฌ๋จผํŠธ๋Š” ๋ฌธ์„œ๋ฅผ ํ‘œํ˜„ํ•˜๋Š” ๋ฐฉ์‹์ด๋ผ๋Š” ์ ์—์„œ ๋” ์—˜๋ฆฌ๋จผํŠธ์™€ ์œ ์‚ฌํ•˜๋‹ค.

```
"์—˜๋ฆฌ๋จผํŠธ(Element)"๋Š” ๋ฆฌ์•กํŠธ ์•ฑ์„ ๊ตฌ์„ฑํ•˜๋Š” ์ตœ์†Œ ๋‹จ์œ„๋‹ค.
```

- React ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์ œ๊ณตํ•˜๋Š” API ์ค‘ ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด ๋ฐ”๋กœ `createElement()` ํ•จ์ˆ˜๋‹ค. ์•„๋ž˜ ์˜ˆ์ œ์—์„œ "Hello world" ๋ฌธ์ž์—ด์„ ๋‹ด์€ h1 ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ๋งŒ๋“ค ๋•Œ ์‚ฌ์šฉํ–ˆ๋‹ค.

```js
React.createElement("h1", null, "Hello World"); // 6
```

- ์ฝ˜์†” ๋กœ๊ทธ๋กœ ๋ฐ˜ํ™˜๋œ ๊ฐ’์„ ์ฐ์–ด๋ณด๋ฉด ๋” ์—˜๋ฆฌ๋จผํŠธ์™€ ๋‹ฌ๋ฆฌ `์ผ๋ฐ˜ ๊ฐ์ฒด`๋‹ค.

```
{
type: "h1",
props: {
children: "Hello World"
}
}
```

- `๊ฐ€์ƒ๋”(Virtual Dom)`์€ ๋ฆฌ์•กํŠธ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ ๋” ์‚ฌ์ด์— ์œ„์น˜ํ•˜๋Š” ๊ณ„์ธต์œผ๋กœ์จ ์ตœ์†Œํ•œ์˜ ์—ฐ์‚ฐ์œผ๋กœ ํ™”๋ฉด์„ ๊ทธ๋ฆฐ๋‹ค.


### ๐Ÿ™„ ReactDOM

- ๋ฆฌ์•กํŠธ๊ฐ€ ๋งŒ๋“  ๊ฐ€์ƒ๋”์€ `์ผ๋ฐ˜ ๊ฐ์ฒด`์ด๋‹ค. ๋ฆฌ์•กํŠธ๊ฐ€ ๊ฐ€์ƒ๋”์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ๋”์„ ์ง์ ‘ ์‚ฌ์šฉํ–ˆ๋‹ค๋ฉด ๋ธŒ๋ผ์šฐ์ €์—์„œ๋งŒ ์‚ฌ์šฉํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ์ œํ•œ๋˜์—ˆ์„์ง€ ๋ชจ๋ฅธ๋‹ค. ํ•˜์ง€๋งŒ ์ผ๋ฐ˜ ๊ฐ์ฒด ๋ชจ์–‘์„ ๊ฐ–๋Š” ๊ฐ€์ƒ๋”์€ ์ด๊ฑธ ๋ Œ๋”๋งํ•˜๋Š” ํ™˜๊ฒฝ์— ๋”ฐ๋ผ ์—ฌ๋Ÿฌ ๊ณณ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
- ๋ฆฌ์•กํŠธ๋ฅผ ์›น ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋™์ž‘ํ•˜๊ฒŒ ํ•˜๋ ค๋ฉด `๊ฐ€์ƒ๋”`์ด ๋” API ํ˜ธ์ถœํ•˜๋„๋ก ํ•˜๋ฉด ๋  ๊ฒƒ์ด๋‹ค. ์ด๋Ÿฌํ•œ ์—ญํ• ์„ ํ•˜๋Š” ๊ฒƒ์ด `ReactDOM` ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋‹ค. ๋ณดํ†ต์€ ์›น ๊ฐœ๋ฐœ์—์„œ ๋ฆฌ์•กํŠธ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ํ•˜๋ฉด `react + reactDOM`์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

```html

```

- ์œ„ ์˜ˆ์ œ๊ฐ€ ๋ฆฌ์•กํŠธ ๋‹ค์Œ์œผ๋กœ ๊ฐ€์ ธ์˜จ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ๋ฐ”๋กœ ReactDOM์ด๋‹ค.

```js
ReactDOM.render(element, document.querySelector("#app")); // 7
```

- ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ๋Š” ๋ฆฌ์•กํŠธ ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ReactDOM.render() ํ•จ์ˆ˜์˜ ์ธ์ž๋กœ ์ „๋‹ฌํ•œ๋‹ค.
- `ReactDOM.render()` ํ•จ์ˆ˜๋Š” `๋ฆฌ์•กํŠธ ์•จ๋ฆฌ๋จผํŠธ`๋ฅผ ๋ฐ›์•„์„œ ๊ฐ€์ƒ๋”์„ ๋งŒ๋“ค๊ธฐ ์‹œ์ž‘ํ•œ๋‹ค.
- ์ด๋ ‡๊ฒŒ ๋งŒ๋“ค์–ด์ง„ ๊ฐ€์ƒ๋”์€ ์ง„์งœ ๋”์— ๋ฐ˜์˜๋˜๊ณ  ๊ทธ ์œ„์น˜๋Š” ๋‘ ๋ฒˆ์งธ ์ธ์ž๋กœ ์ „๋‹ฌํ•œ ์•„์ด๋”” `app`์˜ ์•จ๋ฆฌ๋จผํŠธ์˜ ์ž์‹์ด๋‹ค. ์ด๋Ÿฐ ๊ณผ์ •์„ ํ†ตํ•ด ๋ฆฌ์•กํŠธ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋”์— ๋ฐ˜์˜๋œ๋‹ค.


### ๐Ÿ™„ Babel

```html

```

- ์ตœ์‹  ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ฌธ๋ฒ•์„ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ๋„๊ตฌ๋กœ ๋Œ€๋ถ€๋ถ„์˜ ๋ธŒ๋ผ์šฐ์ ธ๋ฅผ ์ง€์›ํ• ์ˆ˜ ์žˆ๋Š” ์ฝ”๋“œ๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค.
- ๋ฆฌ์•กํŠธ ๊ณต์‹๋ฌธ์„œ์—๋Š” ๋ฐ”๋ฒจ ๋”ฐ์œ„์˜ ํŠธ๋žœ์ŠคํŒŒ์ผ๋Ÿฌ ์—†์ด๋„ ๊ฐœ๋ฐœํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ์•ˆ๋‚ดํ•œ๋‹ค.

```
https://ko.reactjs.org/docs/react-without-es6.html
```

- ํ•˜์ง€๋งŒ ์‹ค์ œ ๊ฐœ๋ฐœ ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ ํ•ด๋ณด๋ฉด ์ด๊ฒƒ๋งŒ์œผ๋กœ๋Š” ๊ธˆ๋ฐฉ ํ•œ๊ณ„๋ฅผ ๋А๋‚€๋‹ค. ์•ž์œผ๋กœ ๋‹ค๋ฃฐ ๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ๋Š” ํด๋ž˜์Šค ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋ณด๋‹ค ํŽธํ•˜๋‹ค.
- ํด๋ž˜์Šค ๋ฌธ๋ฒ•์„ ํฌํ•จํ•œ ์ตœ์‹  ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ๋ฐ”๋ฒจ์ด ํ•„์š”ํ•˜๋‹ค. ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์•ž์œผ๋กœ ์†Œ๊ฐœํ•  JSX ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•  ๋•Œ์—๋„ ๋ฐ”๋ฒจ์ด ํ•„์š”ํ•˜๋‹ค.
- ๋ณดํ†ต์€ ํ„ฐ๋ฏธ๋„ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜๊ฑฐ๋‚˜ ์›นํŒฉ๊ฐ™์€ ๋ฒˆ๋“ค๋Ÿฌ๋กœ ํ†ตํ•ฉํ•ด์„œ ์‚ฌ์šฉํ•œ๋‹ค.


### ๐Ÿ™„ ํ…œํ”Œ๋ฆฟ ์–ธ์–ด

- ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ์ƒ์„ฑํ•  ๋•Œ `document.createElement()` ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
- ํŠธ๋ฆฌ ํ˜•ํƒœ์˜ ๋”์— ๋งž๊ฒŒ ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ๊ตฌ์„ฑํ•˜๋ ค๋ฉด ์—˜๋ฆฌ๋จผํŠธ ๊ฐ„์˜ `๋ถ€๋ชจ-์ž์‹` ๊ด€๊ณ„๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค.

```js
const h1 = document.createElement("h1"); // 1
const header = document.createElement("header"); // 2
header.appendChild(h1); // 3
```

- ์—˜๋ฆฌ๋จผํŠธ h1์„ ๋งŒ๋“ค๊ณ `(1)` ์ด๊ฑธ ์ž์‹์œผ๋กœ ๊ฐ–์„ header ์—˜๋ฆฌ๋จผํŠธ๋„ ๋งŒ๋“ ๋‹ค`(2)`. ๊ทธ๋ฆฌ๊ณ  ๋‚˜์„œ appendChild() ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ด h1์„ header์˜ ์ž์‹ ์—˜๋ฆฌ๋จผํŠธ๋กœ ๋งŒ๋“ค์—ˆ๋‹ค`(3)`.
- ํŠธ๋ฆฌ ํ˜•ํƒœ์˜ ์›น ๋ฌธ์„œ ๊ตฌ์กฐ์ƒ ์ด๋Ÿฐ ์ฝ”๋“œ๋Š” ๋Š˜์–ด๋‚˜๊ธฐ ๋งˆ๋ จ์ด๋‹ค. ๋ฌธ์ œ๋Š” UI๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ์ฝ”๋“œ๊ฐ€ ์ฝ๊ธฐ ์–ด๋ ต๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ์ฝ”๋“œ๋ฅผ ์œ ์‹ฌํžˆ ๋“ค์—ฌ๋‹ค ๋ด์•ผ๋งŒ UI๋ฅผ ๊ฐ€๋Š ํ•  ์ˆ˜ ์žˆ๋‹ค.
- ๊ทธ๋ž˜์„œ ๋Œ€์•ˆ์œผ๋กœ ๋‚˜์˜ค๋Š” ๊ฒƒ์ด `ํ…œํ”Œ๋ฆฟ ์–ธ์–ด`๋‹ค. ํ•ธ๋“ค๋ฐ”, Pug๊ฐ€ ๋Œ€ํ‘œ์ ์ด๊ณ  ์•ต๊ทค๋Ÿฌ์™€ Vue.js๋„ ๋‚˜๋ฆ„์˜ ํ…œํ”Œ๋ฆฟ ๊ธฐ๋Šฅ์„ ์ง€์›ํ•œ๋‹ค.
- ๋ฆฌ์•กํŠธ ์ž์ฒด๋Š” ํ…œํ”Œ๋ฆฟ ์–ธ์–ด๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋‹ค. ๊ทธ์•ผ๋ง๋กœ UI๋งŒ ๋‹ด๋‹นํ•˜๋Š” ์•„์ฃผ ์ž‘์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
- ๋ฆฌ์•กํŠธ ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ํ•จ์ˆ˜์ธ `createElement()`๋กœ ์ž์‹ ์š”์†Œ๋ฅผ ์ถ”๊ฐ€ํ• ์ˆ˜๋Š” ์žˆ์ง€๋งŒ ์ฉ ์‰ฌ์šด ํŽธ์€ ์•„๋‹ˆ๋‹ค.

```js
const h1 = React.createElement("h1", null, "Hello world");
const header = React.createElement("header", null, h1);
```

- ๊ฐœ๋ฐœ์„ ํ•  ์ˆ˜๋Š” ์žˆ์ง€๋งŒ ๊ฐœ๋ฐœํ•ด์•ผ UI๊ฐ€ ๋Š˜์–ด๋‚  ์ˆ˜๋ก ๋ถˆํŽธํ•œ ๊ฒƒ์ด ์‚ฌ์‹ค์ด๋‹ค. ์ฝ๊ธฐ ์–ด๋ ค์šด ์ฝ”๋“œ๊ฐ€ ๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
- ๋ฆฌ์•กํŠธ์—์„œ๋Š” `JSX`๋ผ๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํ™•์žฅ ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•œ๋‹ค.


### ๐Ÿ™„ JSX(JavaScript XML)

- `JSX(JavaScript XML)`๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ํ™•์žฅ ๋ฌธ๋ฒ•์ด๋‹ค. UI ๋‹ค๋ฃจ๋Š” ์ฝ”๋“œ์˜ ๊ฐ€๋…์„ฑ์„ ๋†’์ด๊ธฐ ์œ„ํ•ด ๊ณ ์•ˆ๋œ ๋ฌธ๋ฒ•์ด๋‹ค. createElement() ํ•จ์ˆ˜๋ฅผ ์ง์ ‘ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹์€ ์ฝ๊ธฐ ์–ด๋ ค์šด UI ์ฝ”๋“œ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ๋ฐ–์— ์—†๋‹ค.
- JSX๋Š” ๋งˆ์น˜ ๋งˆํฌ์—… ๋ฌธ๋ฒ• ๊ฐ™๋‹ค.

```js

Hello world


// React.createElement('h1', null, 'Hello world')
```

- JSX๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฆฌ์•กํŠธ UI ์ฝ”๋“œ์˜ ๋ชจ์Šต์ด HTML๊ณผ ๋‹ฎ๋Š”๋‹ค. ๋” ๊ตฌ์กฐ์™€ ์œ ์‚ฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ฝ”๋“œ๋กœ๋ถ€ํ„ฐ UI์„ ์‰ฝ๊ฒŒ ์ถ”์ธกํ•  ์ˆ˜ ์žˆ๋‹ค.
- JSX๋กœ ๋งŒ๋“  ์ฝ”๋“œ๋Š” `๋ฐ”๋ฒจ`์— ์˜ํ•ด ๋ณ€ํ™˜๋˜๋Š”๋ฐ `React.crateElement()` ํ•จ์ˆ˜ ํ˜ธ์ถœ๋กœ ๋Œ€์ฒด ๋œ๋‹ค. `๋ฐ”๋ฒจ REPL`์—์„œ ์ง์ ‘ JSX ์ฝ”๋“œ๊ฐ€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ ๋ณ€ํ™˜๋˜๋Š” ๋ชจ์Šต์„ ํ™•์ธํ•ด ๋ณด์ž.
- ๋ถ€๋ชจ/์ž์‹ ๊ด€๊ณ„๋„ HTML๊ณผ ๊ฐ™๋‹ค.

```jsx

Hello world

```

- ํ™•์‹คํžˆ UI ์ฝ”๋“œ์˜ ๊ฐ€๋…์„ฑ์ด ๊ฐœ์„ ๋˜์—ˆ๋‹ค. ์ด๊ฒƒ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋ฐ”๋ฒจ์— ์˜ํ•ด `React.createElement()` ํ•จ์ˆ˜ ํ˜ธ์ถœ๋กœ ๋ณ€ํ™˜๋œ๋‹ค.
- ๋ฆฌ์•กํŠธ ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋•Œ๋ฌธ์— `ReactDOM.render()`์˜ ์ธ์ž๋กœ ์ „๋‹ฌ๋  ์ˆ˜ ์žˆ๋‹ค.

```jsx
// 1
const element = (

Hello world



);

// 2
ReactDOM.render(element, document.querySelector("#app"));
```

- JSX๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํ‘œํ˜„์‹์ด๊ธฐ ๋•Œ๋ฌธ์— `๊ฐ’`์œผ๋กœ `ํ‰๊ฐ€`๋˜๊ณ  ๋ฐ˜ํ™˜๋œ ๋ฆฌ์•กํŠธ ์•จ๋ฆฌ๋จผํŠธ๋ฅผ element ์ƒ์ˆ˜์— ํ• ๋‹นํ–ˆ๋‹ค`(1)`.
- ์ด ์—˜๋ฆฌ๋จผํŠธ๋ฅผ `ReactDOM.render()`์— ์ „๋‹ฌํ•˜๋ฉด `๊ฐ€์ƒ๋”(Virtual Dom)`์„ ๋งŒ๋“ค๊ณ  ์ด๊ฑธ `#app` ์—˜๋ฆฌ๋จผํŠธ์— ๋ถ™์—ฌ ๋ Œ๋”๋ง๋˜๊ณ  ์šฐ๋ฆฌ๋ˆˆ์— hello world๋ž€ ํ…์ŠคํŠธ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด๋‹ค.


### ๐Ÿค“ ์ค‘๊ฐ„ ์ ๊ฒ€

- ๋ฆฌ์•กํŠธ ์•ฑ์„ ์ด๋ฃจ๋Š” ์ตœ์†Œ๋‹จ์œ„๊ฐ€ `๋ฆฌ์•กํŠธ ์—˜๋ฆฌ๋จผํŠธ`์ธ๋ฐ ์ด๊ฑธ ๋ฆฌ์•กํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ `React.createElement()` ํ•จ์ˆ˜๋กœ ๋งŒ๋“ค์ˆ˜ ์žˆ๋‹ค.
- ๋ฆฌ์•กํŠธ ์—˜๋ฆฌ๋จผํŠธ๋ฅผ `๊ฐ€์ƒ ๋”`์œผ๋กœ ๋งŒ๋“ค์–ด ์‹ค์ œ ๋”์— ๋ฐ˜์˜ํ•ด ์ฃผ๋Š” ๊ฒƒ์ด ๋ฐ”๋กœ `ReactDOM`์˜ ์—ญํ• ์ด๋‹ค. ๋ฆฌ์•กํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋ฐ˜๋“œ์‹œ ์ด ๋‘ ๊ฐœ์˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.
- ๋ฆฌ์•กํŠธ ์ฝ”๋”ฉ์„ ํŽธํ•˜๊ฒŒ ํ•˜๋ ค๋ฉด `๋ฐ”๋ฒจ`๊ฐ™์€ ํŠธ๋žœ์ŠคํŒŒ์ผ๋Ÿฌ์˜ ๋„์›€์„ ๋ฐ›๋Š” ๊ฒƒ์ด ์ข‹๋‹ค. ํด๋ž˜์Šค, JSX ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ๋” ํ•ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
- JSX๋Š” `UI ์ฝ”๋“œ์˜ ๊ฐ€๋…์„ฑ`์„ ๋†’์—ฌ์ค€๋‹ค. ํ•จ์ˆ˜ ํ˜ธ์ถœ๋งŒ์œผ๋กœ๋„ ๋ฆฌ์•กํŠธ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœ์ด ๊ฐ€๋Šฅํ•˜์ง€๋งŒ ์•ฝ๊ฐ„์˜ ๋ฌธ๋ฒ•์„ ๊ฐ€๋ฏธํ•˜๋ฉด ์ƒ๊ฐ๋ณด๋‹ค UI ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์ด ํŽธํ•ด์ง„๋‹ค.


## ๐Ÿ“– ch-3 React ์‚ฌ์šฉํŽธ

### ๐Ÿ™„ ๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ

- ์—˜๋ฆฌ๋จผํŠธ๊ฐ€ ๋ฆฌ์•กํŠธ ์•ฑ์„ ๊ตฌ์„ฑํ•˜๋Š” ์ตœ์†Œ๋‹จ์œ„๋ผ๋ฉด, ์ปดํฌ๋„ŒํŠธ๋Š” UI๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ์—˜๋ฆฌ๋จผํŠธ์™€ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋กœ์ง์„ ํฌํ•จํ•œ `์ƒ์œ„ ๊ฐœ๋…`์ด๋‹ค.
- ๋กœ์ง์€ ์ปดํฌ๋„ŒํŠธ์˜ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•˜๋ฉด์„œ UI ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ์ œ์–ดํ•œ๋‹ค. ์šฐ๋ฆฌ๊ฐ€ ํ•˜๋ ค๋Š” ๊ฒƒ์€ ์ž…๋ ฅ ๊ฐ’์ด๋ผ๋Š” ์ƒํƒœ๋ฅผ ๊ธฐ์–ตํ•˜๋ ค๋Š” ๊ฒƒ์ด๋‹ค. ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ ํ•ฉํ•˜๋‹ค.

```jsx
// 1
class App extends React.Component {
render() {
// 2
return (
<>

๊ฒ€์ƒ‰








>
);
}
}

ReactDOM.render(, document.querySelector("#app")); // 3
```

- ๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ๋Š” React ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์ œ๊ณตํ•œ `Component ํด๋ž˜์Šค`๋ฅผ `์ƒ์†`ํ•ด์„œ ๋งŒ๋“œ๋Š”๋ฐ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋‚˜ํƒ€๋‚ด๋Š” App ์ปดํฌ๋„ŒํŠธ๋กœ ์ด๋ฆ„ ์ง€์—ˆ๋‹ค(1).
- ๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ ๊ตฌ์„ฑ ์š”์†Œ ์ค‘ `render()` ๋ฉ”์„œ๋“œ๋Š” ๋ฆฌ์•กํŠธ ์•ฑ์˜ ๊ธฐ๋ณธ ๊ตฌ์„ฑ ์š”์†Œ์ธ ๋ฆฌ์•กํŠธ ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•ด์„œ ๋”์„ ๋งŒ๋“œ๋Š” ์—ญํ• ์„ ํ•œ๋‹ค(2).


### ๐Ÿ™„ State

- ๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ ๊ตฌ์„ฑ์š”์†Œ ์ค‘ state๋Š” `์ปดํฌ๋„ŒํŠธ์˜ ์ƒํƒœ๋ฅผ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•œ ์šฉ๋„`์ด๋‹ค. ์ด๊ฒƒ์€ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์œ ์ง€ํ•ด์•ผ ํ•  ๊ฐ’์œผ๋กœ์„œ `์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์—์„œ๋งŒ ์ ‘๊ทผ`ํ•  ์ˆ˜ ์žˆ๋Š” ์†์„ฑ์„ ๊ฐ€์ง„๋‹ค.
- ํด๋ž˜์Šค์—์„œ state๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด `์ƒ์„ฑ์ž ํ•จ์ˆ˜`์—์„œ `๋ฉค๋ฒ„ ๋ณ€์ˆ˜`๋กœ ๋“ฑ๋กํ•ด ์ดˆ๊ธฐ๊ฐ’์„ ์„ค์ •ํ•œ๋‹ค.

```jsx
constructor() {
super() // 1
this.state = { searchKeyword: "" } // 2
}
```

- App ํด๋ž˜์Šค๋Š” React.Component ํด๋ž˜์Šค๋ฅผ ์ƒ์†ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ƒ์„ฑ ์‹œ์ ์— `๋ถ€๋ชจ์˜ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœ`ํ•ด์•ผ ํ•œ๋‹ค(1). ๊ทธ๋ฆฌ๊ณ  ๋‚˜์„œ ์ƒ์„ฑ๋œ `this`์— `state`๋ž€ ๊ฐ์ฒด๋ฅผ ๋“ฑ๋กํ•ด ์ƒํƒœ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค(2).


### ๐Ÿ™„ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ

- ์ธํ’‹ ์š”์†Œ์— ๋ฌธ์ž๋ฅผ ์ž…๋ ฅํ•˜๋ฉด `change` ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. ์ด ์ด๋ฒคํŠธ๋ฅผ ์ˆ˜์‹ ํ•˜๋ฉด ์ž…๋ ฅํ•œ ๊ฐ’์„ ์•Œ ์ˆ˜ ์žˆ๋Š”๋ฐ ์ด๊ฑธ๋กœ ์ƒํƒœ๋ฅผ ๊ฐฑ์‹ ํ•˜๋ฉด ๋˜์ง€ ์•Š์„๊นŒ?
- ์ปดํฌ๋„ŒํŠธ์˜ state๋Š” input ์—˜๋ฆฌ๋จผํŠธ์˜ value์— ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ž…๋ ฅํ•œ ๊ฐ’์ด ๊ณง์žฅ ์ธํ’‹ ์—˜๋ฆฌ๋จผํŠธ์— ํ‘œ์‹œ๋  ๊ฒƒ์ด๋‹ค.
- ๋ฆฌ์•กํŠธ์—์„œ ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ์‹์€ ์ผ๋ฐ˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๊ณผ ์œ ์‚ฌํ•˜๋‹ค. ๋‹ค๋งŒ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ์ด๋ฆ„์ด ์กฐ๊ธˆ ๋‹ค๋ฅด๋‹ค. ์•ž์„œ JSX์—์„œ๋„ ์†Œ๊ฐœ ํ–ˆ๋“ฏ์ด HTML์—์„œ change ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋ ค๋ฉด `onchange` ๋ผ๋Š” ์ด๋ฆ„์˜ ์†์„ฑ์„ ์‚ฌ์šฉํ•˜์ง€๋งŒ ๋ฆฌ์•กํŠธ์—๋Š” onChange๋กœ `์นด๋ฉœ์ผ€์ด์Šค`๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

```jsx
this.handleChangeInput(e)} // 1
/>
```

- change ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ํด๋ž˜์Šค์˜ handleChange ๋ฉ”์„œ๋“œ๊ฐ€ ์ฒ˜๋ฆฌํ•˜๋„๋ก ์—ฐ๊ฒฐํ–ˆ๋‹ค.
- value ์†์„ฑ๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ onChange๋„ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํ‘œํ˜„์‹์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ์ค‘๊ด„ํ˜ธ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. ์ต๋ช… ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ–ˆ๋Š”๋ฐ ๊ฐ์ฒด๋กœ ๋ฐ›์€ `์ด๋ฒคํŠธ ๊ฐ์ฒด`๋ฅผ ๊ณง์žฅ `handleChangeInput() ๋ฉ”์„œ๋“œ์— ์ „๋‹ฌํ•œ๋‹ค.`

```jsx
handleChangeInput(event) {
const searchKeyword = event.target.value
this.searchKeyword = searchKeyword
this.forceUpdate() // 1
}
```

- handleChangeInput() ์ด๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ํ•ธ๋“ค๋Ÿฌ ์ด๋ฆ„์„ ์ •ํ–ˆ๋‹ค(1). `handle*`๋กœ ์‹œ์ž‘ํ•˜๋Š” ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ์ด๋ฆ„์€ ๋ฆฌ์•กํŠธ ๊ด€๋ก€๋ฅผ ๋”ฐ๋ž๋‹ค.
- ์ธํ’‹ ์—˜๋ฆฌ๋จผํŠธ์— ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋Š” ์ƒํƒœ๋ฅผ ์ด ๊ฐ’์œผ๋กœ ๊ฐฑ์‹ ํ•˜๋ฉด ํ™”๋ฉด์ด ๋ฐ˜์‘ํ•  ๊ฒƒ์ด๋‹ค. ํ•˜์ง€๋งŒ ์œ„ ์ฝ”๋“œ์ฒ˜๋Ÿผ ์ง์ ‘ state ๊ฐ์ฒด๋ฅผ ์ง์ ‘ ์ˆ˜์ •ํ•˜๋ฉด ๋ฆฌ์•กํŠธ ์•จ๋ฆฌ๋จผํŠธ๊ฐ€ ๋ฐ˜์‘ํ•˜์ง€ ์•Š๋Š”๋‹ค.
- ๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ๋Š” ์Šค์Šค๋กœ ๊ทธ๋ ค์ ธ์•ผ ํ•  ๋•Œ๋ฅผ ์•Œ๊ณ  ์žˆ๊ณ  ํ•„์š”ํ•  ๋•Œ๋งŒ `render()` ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ด์„œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋‹ค์‹œ ๊ทธ๋ฆฐ๋‹ค. ๋งŒ์•ฝ `๊ฐ•์ œ๋กœ ์ปดํฌ๋„ŒํŠธ์˜ render() ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœ`ํ•˜๋ ค๋ฉด ํด๋ž˜์Šค์˜ `forceUpdate()` ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

```jsx
handleChangeInput(event) {
const searchKeyword = event.target.value
this.setState({ searchKeyword }) // 1
}
```

- ๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ๊ฐ€ `์Šค์Šค๋กœ ์ƒํƒœ์˜ ๋ณ€ํ™”๋ฅผ ์ธ์ง€`ํ•˜๊ณ  `render()๋ฅผ ํ˜ธ์ถœ`ํ•˜๋„๋ก ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ํ•„์š”ํ•˜๋‹ค. ๊ธฐ์–ตํ•˜์ž!! ํ•ญ์ƒ ์ปดํฌ๋„ŒํŠธ์˜ ์ƒํƒœ๋ฅผ ๊ฐฑ์‹ ํ•˜๋ ค๋ฉด `setState()` ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์ž!
- ํด๋ž˜์Šค๊ฐ€ ์ œ๊ณตํ•˜๋Š” setState() ๋ฉ”์„œ๋“œ๋กœ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ–ˆ๋‹ค. ์ด ๋ฉ”์„œ๋“œ๋Š” ์ปดํฌ๋„ŒํŠธ์˜ ์ƒํƒœ๋ฅผ ๋ณ€ํ™”์‹œํ‚ค๊ฒ ๋‹ค๋Š” ์ปดํฌ๋„ŒํŠธ์™€์˜ ์ง์ ‘์ ์ธ ์•ฝ์†์ด๋‹ค.
- ์ด ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๋น„๋กœ์†Œ ์ปดํฌ๋„ŒํŠธ๋Š” ์ƒํƒœ ๋ณ€ํ™”๋ฅผ ์•Œ ์ˆ˜ ์žˆ๊ณ  ๋‹ค์‹œ ๊ทธ๋ ค์•ผํ• ์ง€ ์—ฌ๋ถ€๋„ ํŒ๋‹จํ•  ์ˆ˜๋„ ์žˆ๋Š” ๊ฒƒ์ด๋‹ค.


### ๐Ÿ™„ ํผ ์ œ์ถœ(submit)๊ณผ ์ดˆ๊ธฐํ™”(reset)

- ํผ์—์„œ ์—”ํ„ฐ๋ฅผ ์ž…๋ ฅํ•˜๋ฉด `submit` ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š”๋ฐ ์ด๋ฅผ ์žก์•„์„œ ์ฒ˜๋ฆฌํ•˜๋ ค๋ฉด, ๋ณ€๊ฒฝ ์ด๋ฒคํŠธ๋ฅผ onChange ์†์„ฑ์œผ๋กœ ๋ฐ›๋“ฏ์ด onSubmit ์†์„ฑ์œผ๋กœ ํผ ์ œ์ถœ(submit)์„ ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.
- form ๋‚ด๋ถ€์—์„œ button์€ ๊ธฐ๋ณธ์ ์œผ๋กœ submit ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

```js
this.handleSubmit(event)}>
```

- button์˜ type="reset" ์†์„ฑ์— ์˜ํ•ด ํผ์— reset ์ด๋ฒคํŠธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.

```js
this.handleReset()}>

```


### ๐Ÿ™„ ๋ฆฌ์ŠคํŠธ์™€ ํ‚ค

- ๋ฆฌ์•กํŠธ ๊ณต์‹ ๋ฌธ์„œ๋ฅผ ์‚ดํŽด๋ณด๋ฉด, `Key๋Š” ์—˜๋ฆฌ๋จผํŠธ์— ์•ˆ์ •์ ์ธ ๊ณ ์œ ์„ฑ์„ ๋ถ€์—ฌํ•˜๊ธฐ ์œ„ํ•ด ๋ฐฐ์—ด ๋‚ด๋ถ€์˜ ์—˜๋ฆฌ๋จผํŠธ์— ์ง€์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.` ๋ผ๊ณ  ์„ค๋ช…์ด ๋‚˜์™€ ์žˆ๋‹ค.
- ์—ฌ๊ธฐ์„œ ๋‹ค์‹œ `๊ฐ€์ƒ๋”(virtual dom)`์ด ๋‚˜์˜จ๋‹ค. ๋ฆฌ์•กํŠธ ์•จ๋ฆฌ๋จผํŠธ๋ฅผ ๊ฐ€์ƒ๋”์œผ๋กœ ๋งŒ๋“ค๊ณ  ์ด์ „ ๊ฐ€์ƒ๋”๊ณผ ์ฐจ์ด๊ฐ€ ์žˆ๋Š” ๋ถ€๋ถ„๋งŒ ๊ณ„์‚ฐํ•ด ์‹ค์ œ ๋”์— ๋ฐ˜์˜ํ•˜๋ฉด์„œ ๋ Œ๋”๋ง ์„ฑ๋Šฅ์„ ์˜ฌ๋ฆฐ๋‹ค๊ณ  ํ–ˆ๋‹ค.
- ์ด๋•Œ, `ํŠธ๋ฆฌ ๋น„๊ต`๋ฅผ ์ง„ํ–‰ํ•˜๋Š”๋ฐ `O(n^3)`๋งŒํผ์˜ ๊ณ„์‚ฐ ๋ณต์žก๋„๋ฅผ ๊ฐ€์ง„๋‹ค. ํ™”๋ฉด์„ ๊ทธ๋ฆด ๋•Œ๋งˆ๋‹ค ์ด๋Ÿฌํ•œ ๊ณ„์‚ฐ์€ ๋น„ํšจ์œจ์ ์ด๊ณ  ํ™”๋ฉด ๋ Œ๋”๋ง์„ ์˜คํžˆ๋ ค ๋А๋ฆฌ๊ฒŒ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ๋‹ค.
- ๊ทธ๋ž˜์„œ ๋‘ ๊ฐ€์ง€ ๊ฐ€์ •ํ•˜์— `์žฌ์กฐ์ •(Reconciliation) ์•Œ๊ณ ๋ฆฌ์ฆ˜`์„ ์‚ฌ์šฉํ•œ๋‹ค. (1) ์•จ๋ฆฌ๋จผํŠธ ํƒ€์ž…์ด ๋‹ค๋ฅผ ๊ฒฝ์šฐ์™€ (2) Key ๊ฐ’์ด ๋‹ค๋ฅผ ๊ฒฝ์šฐ, ๊ฐ ๊ฐ ํ™”๋ฉด์„ ์กฐ์ •ํ•˜๋„๋ก ํ•˜๋Š”๋ฐ `O(n)`์œผ๋กœ ๊ณ„์‚ฐ ๋ณต์žก๋„๊ฐ€ ํ™•์—ฐํ•˜๊ฒŒ ์ค„์–ด๋“ ๋‹ค๊ณ  ํ•œ๋‹ค.
- ๋ฆฌ์ŠคํŠธ ์•จ๋ฆฌ๋จผํŠธ๋Š” li๋ฅผ ์—ฌ๋Ÿฌ ๊ฐœ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์•จ๋ฆฌ๋จผํŠธ ํƒ€์ž…์œผ๋กœ ์ฐจ์ด๋ฅผ ํŒ๋‹จํ•  ์ˆ˜๋Š” ์—†๊ณ  ์ด ๊ฒฝ์šฐ `์œ ์ผํ•œ ๊ฐ’์„ key ์†์„ฑ์— ์‚ฌ์šฉ`ํ•จ์œผ๋กœ์จ ๋ฆฌ์•กํŠธ๊ฐ€ ์ด์ „ ๊ฐ€์ƒ๋”๊ณผ ์ฐจ์ด๋ฅผ ๊ณ„์‚ฐํ•˜๋„๋ก ์•Œ๋ ค์•ผ ํ•œ๋‹ค. ๋ณดํ†ต ๋ฐ์ดํ„ฐ์˜ `์•„์ด๋”” ๊ฐ’`์„ ์‚ฌ์šฉํ•˜๊ธฐ๋ฅผ ๊ถŒ์žฅํ•œ๋‹ค.

```jsx


  • ```

    - ๋ฐฐ์—ด ๋ฉ”์„œ๋“œ์ธ `map()`์„ ์‚ฌ์šฉํ•ด์„œ์ธ์ง€ ๋ฉ”์„œ๋“œ์˜ ๋‘๋ฒˆ ์งธ ์ธ์ž์ธ `index`๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ๋„ ํ•œ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด๊ฒƒ์€ ๊ณ ์œ ํ•œ ๊ฐ’์ด ์—†์„ ๊ฒฝ์šฐ `์ตœํ›„์˜ ์ˆ˜๋‹จ`์œผ๋กœ ๊ณ ๋ คํ•˜๊ณ  `์ง€์–‘`ํ•˜๋Š” ๊ฒƒ์ด ์˜ณ๋‹ค. ์„ฑ๋Šฅ ์ €ํ•˜๋‚˜ ํ™”๋ฉด์ด ๊ฐฑ์‹ ๋˜์ง€ ์•Š๋Š” ๋ฌธ์ œ๋ฅผ ๋‚ดํฌํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.


    ### ๐Ÿ™„ ๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ์˜ ์ƒ๋ช…์ฃผ๊ธฐ

    - ์ปดํฌ๋„ŒํŠธ ์ƒํƒœ ๋“ฑ ์ดˆ๊ธฐํ™” ์ž‘์—…์„ ์™„๋ฃŒํ•˜๋ฉด ์ปดํฌ๋„ŒํŠธ ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋œ๋‹ค`(constructor)`
    - ๊ทธ๋ฆฌ๊ณ  ๋ฆฌ์•กํŠธ ์•จ๋ฆฌ๋จผํŠธ๋ฅผ ์ด์šฉํ•ด ๊ฐ€์ƒ๋”์„ ๊ทธ๋ฆฌ๊ณ  ์ด๊ฑธ ์‹ค์ œ ๋”์— ๋ฐ˜์˜ํ•œ๋‹ค`(render)`
    - ๋”์— ๋ฐ˜์˜๋˜๋Š” ๊ฒƒ์„ ๋งˆ์šดํŠธ๋œ๋‹ค๋ผ๊ณ  ํ‘œํ˜„ํ•˜๋Š”๋ฐ ๋งˆ์šดํŠธ๊ฐ€ ์™„๋ฃŒ๋˜๋ฉด`(componentDidMount)` ์ด๋ฒคํŠธ๋ฅผ ๋ฐ”์ธ๋”ฉํ•˜๊ฑฐ๋‚˜ ์™ธ๋ถ€ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋“ฑ์˜ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•œ๋‹ค
    - ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์‚ฌ๋ผ์ง€๊ธฐ ์ „์— ์ฆ‰ ๋งˆ์šดํŠธ ์ง์ „์—๋Š”`(compoentWillUnmount)` ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ œ๊ฑฐํ•˜๋Š” ๋“ฑ ๋ฆฌ์†Œ์Šค ์ •๋ฆฌ ์ž‘์—…์„ ํ•œ๋‹ค
    - ๋งˆ์ง€๋ง‰์œผ๋กœ ์ปดํฌ๋„ŒํŠธ๋Š” ๋ณธ์ธ์˜ ์‚ถ์„ ๋งˆ๊ฐํ•˜๋Š” ์ˆœ์„œ๋ฅผ ๋”ฐ๋ฅธ๋‹ค


    ### ๐Ÿ™„ ์ด๋ฒคํŠธ ์ „ํŒŒ๋ฅผ ๋ง‰๋Š” stopPropagation()

    - `stopPropagation()`์€ ๋ฒ„๋ธ”๋ง๊ณผ ์บก์ณ๋ง ๊ฐ™์€ ์ „ํŒŒ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ๊ทธ๋ƒฅ ์›ํ•˜๋Š” ํƒœ๊ทธ์—์„œ์˜ ์ด๋ฒคํŠธ๋งŒ ์‹ ๊ฒฝ์“ฐ๊ณ  ์‹ถ์„ ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ๋ฉ”์„œ๋“œ์ด๋‹ค.

    ```js
    const keywordList = (


      {this.state.keywordList.map((item, idx) => (
    • this.search(item.keyword)}>
      {idx + 1}
      {item.keyword}

    • ))}

    );
    ```

    - button์„ ํด๋ฆญํ•˜๋ฉด ์ƒ๋‹จ์— ์žˆ๋Š” li์˜ click์ด๋ฒคํŠธ๊ฐ€ ๋ฒ„๋ธ”๋ง์„ ํ†ตํ•ด์„œ ๊ฐ™์ด ์‹คํ–‰๋˜๋Š” ์˜ˆ์ œ์ด๋‹ค. ์ด๊ฒƒ์€ ์˜๋„์น˜ ์•Š์€ ๊ฒฐ๊ณผ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

    ```js
    handleRemoveHistory(e, keyword) {
    e.stopPropagation();

    store.removeHistory(keyword);
    const historyList = store.getHistoryList();
    this.setState({ historyList });
    }
    ```

    - ์ด๋Ÿฐ ์ƒํ™ฉ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด์„œ `stopPropagation()`์„ ์‚ฌ์šฉํ–ˆ๋‹ค. `stopPropagation()`์„ ์ถ”๊ฐ€ํ•จ์œผ๋กœ์จ ์ด๋ฒคํŠธ ์ „ํŒŒ๋Š” ๋™์ž‘ํ•˜์ง€ ์•Š๊ณ  button ํƒœ๊ทธ ๋‚ด์—์„œ๋งŒ ํด๋ฆญ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.


    ## ๐Ÿ“– ch-4 ์ปดํฌ๋„ŒํŠธ

    ### ๐Ÿ™„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ 

    - ๊ด€๋ จ๋œ ์ฝ”๋“œ ๋ฉ์–ด๋ฆฌ๋ฅผ ๋ชจ์•„ ํ•˜๋‚˜์˜ ๋…๋ฆฝ๋œ ๊ฐœ๋…์œผ๋กœ `์ถ”์ƒํ™”`ํ•˜๋Š” ๊ธฐ๋ฒ•์€ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ ๊ฐœ๋ฐœ์ž์˜ ์‚ฌ๊ณ ๋ ฅ์„ ๋น„์•ฝ์ ์œผ๋กœ ๋†’์—ฌ์ค€๋‹ค.
    - ์ƒํƒœ์™€ UI ์ฝ”๋“œ๋กœ ์ด๋ฃจ์–ด์ง„ ํ™”๋ฉด ๊ฐœ๋ฐœ์—์„œ๋„ `์ปดํฌ๋„ŒํŠธ`๋ผ๋Š” ๊ฐœ๋…์„ ์‚ฌ์šฉํ•ด `์ถ”์ƒํ™”` ํ•  ์ˆ˜ ์žˆ๋‹ค.


    ### ๐Ÿ™„ ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์ปดํฌ๋„ŒํŠธ๋กœ ๊ฐœ์„ 

    - ๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ์—์„œ UI ์ƒํƒœ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์€ state ๋ง๊ณ ๋„ `props`๊ฐ€ ์žˆ๋‹ค.
    - State๊ฐ€ ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์—์„œ ๊ด€๋ฆฌ๋Š” ์ƒํƒœ๋ผ๋ฉด props๋Š” ์ปดํฌ๋„ŒํŠธ ์™ธ๋ถ€์—์„œ ๋“ค์–ด์™€ ๋‚ด๋ถ€ UI์— ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์žˆ๋Š” ๋…€์„์ด๋‹ค.
    - ์ด ๊ฐ’์— ์˜์กดํ•œ ๋ฆฌ์•กํŠธ ์•จ๋ฆฌ๋จผํŠธ๋ฅผ ๋งŒ๋“ค๋ฉด props ๋ณ€ํ™”์— ๋”ฐ๋ผ UI๊ฐ€ ๋ฆฌ์•กํ‹ฐ๋ธŒํ•˜๊ฒŒ ๋ฐ˜์‘ํ•œ๋‹ค.

    ```jsx
    // App.js
    class App extends React.Component {
    render() {
    return ; // 3
    }
    }

    // Header.js
    const Header = ({ title }) => {
    return (

    {title}



    );
    };
    ```

    - Props๋Š” `๊ฐ์ฒด ๋ชจ์–‘`์œผ๋กœ ์ปดํฌ๋„ŒํŠธ๋กœ ์ „๋‹ฌ๋œ๋‹ค. ์ด ๊ฐ’์œผ๋กœ ๋ฆฌ์•กํŠธ ์•จ๋ฆฌ๋จผํŠธ๋ฅผ ๋งŒ๋“ ๋‹ค. ์ปดํฌ๋„ŒํŠธ์˜ props๋Š” ์†์„ฑ ์ด๋ฆ„์œผ๋กœ ์ „๋‹ฌํ•œ๋‹ค. Hello ์ปดํฌ๋„ŒํŠธ๋Š” ์ „๋‹ฌ๋œ `name ๊ฐ’`์— ๋”ฐ๋ผ UI๊ฐ€ ๋ณ€๊ฒฝ๋  ๊ฒƒ์ด๋‹ค.


    ### ๐Ÿ™„ ์กฐํ•ฉ: ์ปดํฌ๋„ŒํŠธ ๋‹ด๊ธฐ

    - ๋ฆฌ์•กํŠธ ํด๋ž˜์Šคํ˜• ์ปดํฌ๋„ŒํŠธ๋Š” ํด๋ž˜์Šค ์ƒ์†์œผ๋กœ ์ปดํฌ๋„ŒํŠธ ์žฌํ™œ์šฉํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•˜์ง€ ์•Š๋Š”๋‹ค.

    ```
    Facebook์—์„œ๋Š” ์ˆ˜์ฒœ ๊ฐœ์˜ React ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์ง€๋งŒ,
    ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ƒ์† ๊ณ„์ธต ๊ตฌ์กฐ๋กœ ์ž‘์„ฑ์„ ๊ถŒ์žฅํ• ๋งŒํ•œ ์‚ฌ๋ก€๋ฅผ ์•„์ง ์ฐพ์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค.
    - ์ถœ์ฒ˜: ๋ฆฌ์•กํŠธ ๋ฌธ์„œ
    ```

    - ๋Œ€์‹ , props๋ฅผ ํ†ตํ•ด ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ•ฉ์„ฑํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•œ๋‹ค.

    ```jsx
    const List = ({ data, onClick, renderItem }) => {
    return (


      {data.map((item, idx) => (
    • onClick(item.keyword)}>
      {renderItem(item, idx)}

    • ))}

    );
    };
    ```

    - ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ๋กœ ๋งŒ๋“  List์ปดํฌ๋„ŒํŠธ์ด๋‹ค. ์™ธ๋ถ€์—์„œ ๋ Œ๋”๋ง์— ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ์ž… ๋ฐ›๊ฒ ๋‹ค๋Š” ์˜๋„์ด๋‹ค.
    - ํ‚ค์›Œ๋“œ ๋ชฉ๋ก ๋ฐ์ดํ„ฐ๋ฅผ props.data๋กœ ๋ฐ›์•˜๋‹ค.
    - ๋ฆฌ์ŠคํŠธ ์ถœ๋ ฅ๊นŒ์ง€๋งŒ ๋‹ด๋‹นํ•˜๊ณ  ๋ฆฌ์ŠคํŠธ๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ๊ฐ ํ•ญ๋ชฉ์„ ์ถœ๋ ฅํ•˜๋Š” ํ•จ์ˆ˜๋Š” props.renderItem์ด๋ž€ ์ด๋ฆ„์œผ๋กœ ์ „๋‹ฌํ•˜๋„๋ก ํ–ˆ๋‹ค.
    - ์ฐธ๊ณ ๋กœ, props์— ํ•จ์ˆ˜๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋Ÿฌํ•œ ํ•จ์ˆ˜ ์ค‘ ๋ฆฌ์•กํŠธ ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ `render props`๋ผ๊ณ  ํ•œ๋‹ค.

    ```jsx
    const KeywordList = ({ onClick }) => {
    const [data, setData] = useState([]);

    const renderItem = useCallback((item, idx) => {
    return (
    <>
    {idx + 1}
    {item.keyword}
    >
    );
    });

    useEffect(() => {
    setData(store.getKeywordList());
    }, []);

    return ;
    };
    ```

    - ์œ„ List ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ด์šฉํ•œ KeywordList ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค.
    - List ์ปดํฌ๋„ŒํŠธ๊ฐ€ `๊ณตํ†ต ๋กœ์ง`๊ณผ `UI`๋ฅผ ๋‹ด๋Š” ์ปดํฌ๋„ŒํŠธ์ด๊ณ , ์ด๋ฅผ ์ด์šฉํ•ด์„œ KeywordList๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค.
    - ํด๋ž˜์Šค ์ƒ์†๊ณผ ๋‹ฌ๋ฆฌ List์•ˆ์— renderItem์ด๋ž€ render props๋ฅผ ์ „๋‹ฌํ•ด์„œ List๊ฐ€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ทธ๋ฆฌ๋„๋ก ํ–ˆ๋‹ค. ๋ฟ๋งŒ์•„๋‹ˆ๋ผ ์ปดํฌ๋„ŒํŠธ ์ž์ฒด๋กœ props๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋‹ค.
    - ์ด๋ ‡๊ฒŒ props๋กœ `์ปดํฌ๋„ŒํŠธ๋ฅผ ์ „๋‹ฌ`ํ•˜๊ฑฐ๋‚˜ `๋ Œ๋”ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ „๋‹ฌ`ํ•˜๋Š” ๋ฐฉ์‹์„ `์ปดํฌ๋„ŒํŠธ ๋‹ด๊ธฐ`๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.


    ### ๐Ÿ™„ ์กฐํ•ฉ: ํŠน์ˆ˜ํ™”

    - ์ปดํฌ๋„ŒํŠธ ๋‹ด๊ธฐ ๋ง๊ณ  ์ปดํฌ๋„ŒํŠธ๋ฅผ ์กฐํ•ฉํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ํŠน์ˆ˜ํ™”๊ฐ€ ์žˆ๋‹ค.

    ```jsx
    onst List = ({ data, onClick, hasIndex, hasDate, onRemove }) => {
    const handleClickRemove = useCallback((e, keyword) => {
    e.stopPropagation();
    onRemove(keyword);
    }, []);

    return (


      {data.map((item, idx) => (
    • onClick(item.keyword)}>
      {hasIndex && {idx + 1}}
      {item.keyword}
      {hasDate && (
      {formatRelativeDate(item.date)}
      )}
      {!!onRemove && (
      handleClickRemove(e, item.keyword)}
      >
      )}

    • ))}

    );
    };
    ```

    - ๊ธฐ์กด์˜ ์ปดํฌ๋„ŒํŠธ ๋‹ด๊ธฐ๋ณด๋‹ค ์™ธ๋ถ€์—์„œ ๋ฐ›๋Š” props๊ฐ€ ์ฆ๊ฐ€ ํ–ˆ๋‹ค. props๋ฅผ ์–ด๋–ป๊ฒŒ ์„ค์ •ํ•˜๋А๋ƒ์— ๋”ฐ๋ผ ์กฐ๊ธˆ์”ฉ ๋‹ค๋ฅธ ๋ชจ์–‘๊ณผ ํ–‰์œ„๋ฅผ ํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“œ๋Š”๋ฐ ์‚ฌ์šฉํ•œ๋‹ค.
    - ์œ„ ์˜ˆ์ œ์—์„œ๋Š” hasIndex๋ฅผ ์„ค์ •ํ•˜๋ฉด ์ขŒ์ธก์— ์ˆœ์„œ๋ฅผ ํ‘œ์‹œํ•˜๋„๋ก ํ–ˆ๊ณ , hasDate์™€ onRemove ํ•จ์ˆ˜์— ๋”ฐ๋ผ ๋‚ ์งœ์™€ ์‚ญ์ œ ๋ฒ„ํŠผ์„ ๋ณด์ด๋„๋ก ํ–ˆ๋‹ค.

    ```jsx
    const KeywordList = ({ onClick }) => {
    const [data, setData] = useState([]);

    useEffect(() => {
    setData(store.getKeywordList());
    }, []);

    return ;
    };

    export default KeywordList;
    ```

    - ์œ„ KeywordList ๋ฆฌ์ŠคํŠธ์—์„œ๋Š” ์ˆœ์„œ์™€ ํ‚ค์›Œ๋“œ๋ฅผ ํ‘œ์‹œํ•˜๊ธฐ์œ„ํ•ด hasIndex๋ฅผ props๋กœ ์ „๋‹ฌํ–ˆ๋‹ค.
    - KeywordList๋Š” ์ˆœ์„œ๊ฐ€ ์žˆ๋Š” List์˜ ํŠน์ˆ˜ํ•œ ๊ฒฝ์šฐ์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.


    ### ๐Ÿ™„ ์ปดํฌ๋„ŒํŠธ ์žฌ์‚ฌ์šฉ ๋ฐฉ๋ฒ• ์ •๋ฆฌ

    - ์ƒ์†. ๊ณตํ†ต ๋กœ์ง์„ ๋ถ€๋ชจ ํด๋ž˜์Šค๊ฐ€ ๊ฐ–๋„๋ก ํ–ˆ๋‹ค. ๋ฆฌ์ŠคํŠธ ์ƒํƒœ๋ฅผ ๊ฐ€์ง€๊ณ  ์ด๋ฅผ ๋ฆฌ์ŠคํŠธ ๋ Œ๋”๋งํ•œ๋‹ค. ์ „ํ†ต์ ์ธ OOP ์Šคํƒ€์ผ์˜ ์ƒ์† ๊ตฌ์กฐ๋ฅผ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์—์„œ๋Š” ์ต์ˆ™ํ•œ ๋ฐฉ์‹์ด๋‹ค. ํ•˜์ง€๋งŒ ์ƒ์† ๋‹จ๊ณ„๊ฐ€ ๋งŽ์•„์ง€๋ฉด ์ฝ”๋“œ๋ฅผ ํŒŒ์•…ํ•˜๋Š”๋ฐ ๋‹ค์†Œ ์–ด๋ ค์šธ ์ˆ˜๋„ ์žˆ๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ๋‹ค. ํŠนํžˆ state์— ๋ฐ˜์‘ํ•˜๋Š” UI ์ฝ”๋“œ๊ฐ€ ์ƒ์† ๊ตฌ์กฐ์— ๊ฐ€๋ ค ์ž˜ ๋ณด์ด์ง€ ์•Š์„ ์ˆ˜๋„ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์˜คํžˆ๋ ค ๋ฆฌ์•กํŠธ ์ปค๋ฎค๋‹ˆํ‹ฐ์—์„œ๋Š” ์ง€์–‘ํ•˜๋Š” ๋ถ„์œ„๊ธฐ์ธ ๊ฒƒ ๊ฐ™๋‹ค.

    ```
    React๋Š” ๊ฐ•๋ ฅํ•œ ํ•ฉ์„ฑ ๋ชจ๋ธ์„ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉฐ, ์ƒ์† ๋Œ€์‹  ํ•ฉ์„ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ปดํฌ๋„ŒํŠธ ๊ฐ„์— ์ฝ”๋“œ๋ฅผ ์žฌ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. - ์ถœ์ฒ˜: ๋ฆฌ์•กํŠธ ๋ฌธ์„œ > ํ•ฉ์„ฑ vs ์ƒ์†
    ```

    - ์กฐํ•ฉ(์ปดํฌ๋„ŒํŠธ ๋‹ด๊ธฐ): ํ•จ์ˆ˜๋ฅผ ์กฐํ•ฉํ•˜๋“ฏ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์กฐํ•ฉํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์ฝ”๋“œ ์žฌํ™œ์šฉ์„ ๊ถŒ์žฅํ•œ๋‹ค. ๋ฆฌ์•กํŠธ์˜ props ์—๋Š” ์–ด๋– ํ•œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ฐ’๋„ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ props๋ฅผ ํ™œ์šฉํ•ด์„œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์กฐํ•ฉํ•œ๋‹ค. ์—ฌ๊ธฐ์„œ๋Š” ๋ Œ๋”๋ง ์šฉ๋„์˜ render props๋ฅผ ์ „๋‹ฌํ–ˆ๋‹ค. ์ด ์™ธ์—๋„ ๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ ์ž์ฒด๋ฅผ ์ „๋‹ฌํ•ด ์กฐํ•ฉํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

    - ์กฐํ•ฉ(ํŠน์ˆ˜ํ™”): ์ด๊ฒƒ๋„ props๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹์ด๋ผ๋Š” ์ ์—์„œ๋Š” ๊ฐ™์ง€๋งŒ ์ ‘๊ทผ์˜ ์ฐจ์ด๋ผ๊ณ  ์ƒ๊ฐํ•œ๋‹ค. KeywordList๋Š” List ์ปดํฌ๋„ŒํŠธ์˜ ํŠน์ˆ˜ํ•œ ๊ฒฝ์šฐ์ด๋‹ค. List ์ปดํฌ๋„ŒํŠธ์— ์ขŒ์ธก ์ˆœ์„œ๊ฐ€ ์žˆ๋Š” ํŠน์ˆ˜ํ•œ ๊ฒฝ์šฐ์ธ ์…ˆ์ด๋‹ค. HistoryList๋„ ๊ทธ๋Ÿฌํ•œ๋ฐ ์šฐ์ธก์— ๋‚ ์งœ์™€ ๋ฒ„ํŠผ์ด ์œ„์น˜ํ•œ List์˜ ํŠน์ˆ˜ํ•œ ๊ฒฝ์šฐ์ธ ๊ฒƒ์ด๋‹ค.