React ์—ฐ๊ตฌ์‹ค

์•ˆ๋…•ํ•˜์„ธ์š”. :smile:

์ œ๊ฐ€ ์š”์ฆ˜ React๋ฅผ ํ•˜๊ฒŒ ๋˜์–ด ์—ด์‹ฌํžˆ ์ผํ•˜๋ฉฐ ๋ฐฐ์šฐ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
๋”๊ตฐ๋‹ค๋‚˜ ์ธํ„ฐ๋„ท์ด ์ฐจ๋‹จ๋˜์–ด ์žˆ๋Š” ํ™˜๊ฒฝ์— ์ฒ˜ํ•˜๋‹ค ๋ณด๋‹ˆ ์Šฌ๋กœ๊ทธ๋ฅผ ์ ๊ทน ํ™œ์šฉํ•ด์•ผ๊ฒ ๋‹ค๋Š” ๋ฌ˜์ˆ˜๊ฐ€ ๋– ์˜ฌ๋ž์Šต๋‹ˆ๋‹ค. :smile:

๋‘์„œ ์—†์ด React์— ๊ด€ํ•œ ๋ฐฐ์›€์˜ ๊ณผ์ •์„ ๊ธฐ๋กํ•˜๋Š” ๊ฒƒ์ด ๋ชฉํ‘œ์ž…๋‹ˆ๋‹ค.


์ฝ์–ด์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!

image

image


image

6๊ฐœ์˜ ์ข‹์•„์š”

10๋ถ„๋งŒ์— ๋ฆฌ์•กํŠธ ์‹œ์ž‘ํ•˜๊ธฐ

  1. ๋น„์ฃผ์–ผ ์ŠคํŠœ๋””์˜ค ์ฝ”๋“œ ์„ค์น˜
  2. node.js ์„ค์น˜
  3. ๋ฆฌ์•กํŠธ ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ
  4. ๋ฆฌ์•กํŠธ ์›น์‚ฌ์ดํŠธ ์‹คํ–‰(๊ตฌ๋™)

1. ๋น„์ฃผ์–ผ ์ŠคํŠœ๋””์˜ค

๋‹ค์šด๋กœ๋“œ ์„ค์น˜ํ•˜๊ธฐ

2. ๋…ธ๋“œ (node.js)

๋‹ค์šด๋กœ๋“œ ์„ค์น˜ํ•˜๊ธฐ

3. ๋ฆฌ์•กํŠธ ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ

cmd, powershell, terminal, visual studio code, node ๋“ฑ์—์„œ ์•„๋ž˜ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

> npm create-react-app myProject

๋˜๋Š”

> npx create-react-app myProject

4. ๋ฆฌ์•กํŠธ ์›น์‚ฌ์ดํŠธ ๊ตฌ๋™

์ƒ์„ฑํ•œ ํ”„๋กœ์ ํŠธ ์œ„์น˜์— ์ ‘๊ทผํ•˜์—ฌ ์•„๋ž˜ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

npm start

image

์ •์ƒ ๊ตฌ๋™๋œ ๋ฆฌ์•กํŠธ ์›น์‚ฌ์ดํŠธ ์ž…๋‹ˆ๋‹ค. :smile:

๊ทธ๋ฆฌ๊ณ  ์•„๋ž˜ ๋ฆฌ์•กํŠธ ์†Œ๊ฐœ ๊ธ€๋„ ์ค€๋น„ํ–ˆ์œผ๋‹ˆ ํ•œ๋ฒˆ ์ฝ์–ด๋ณด์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค.

๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. :smile:

1๊ฐœ์˜ ์ข‹์•„์š”

๋ฆฌ์•กํŠธ ์œ ์ €์ปจํŠธ๋กค ๋งŒ๋“ค๊ธฐ

๋ฆฌ์•กํŠธ์—์„œ๋Š” Component ๋ผ๊ณ  ์ง€์นญํ•˜์ง€๋งŒ ์œ ์ €์ปจํŠธ๋กค ์ด๋ผ ๋ถ€๋ฅด๋Š” ๊ฒƒ์ด ์ €๋Š” ๋” ์ข‹์œผ๋‹ˆ๊นŒ, ์–ด๋–ป๊ฒŒ ๋ถ€๋ฅด๋“  ์ƒ๊ด€์—†์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๊ธฐ๋ณธ ์‚ฌ์šฉ ๋ฐฉ๋ฒ•๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜๊ธฐ์—๋Š” ์ธ๋‚ด์‹ฌ์ด ๋ถ€์กฑํ•ฉ๋‹ˆ๋‹ค.
์•„๋ž˜๋Š” ํฅ๋ฏธ๋ฅผ ๋•๊ธฐ ์œ„ํ•ด ์ค€๋น„ํ•œ ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค.

๋ฆฌ์•กํŠธ๊ฐ€ ์›น์„ ์–ผ๋งˆ๋‚˜ ์žฌ๋ฏธ์žˆ๊ฒŒ ํ•˜๊ณ  ์žˆ๋Š”์ง€ ๋ณผ๊นŒ์š”??

Title ์œ ์ €์ปจํŠธ๋กค ๋งŒ๋“ค๊ธฐ

ํ”„๋กœ์ ํŠธ/src/usercontrols/Title.js

import React from "react";

export default function Title() {
    return (
        <div>
            Dotnet DEV
        </div>
    );
}

์ฐธ์กฐ ๋ถ€๋ถ„์€ ๋งˆ์น˜ Python์„ ์—ฐ์ƒ์ผ€๋„ ํ•˜๋Š”๊ตฐ์š”.

from selenium import webdriver

๊ทธ๋ฆฌ๊ณ  ๊ฐ‘์ž๊ธฐ ๊ถ๊ธˆํ•ด์„œ dJango๋„ React์™€ ๋น„์Šทํ• ์ง€ ํ™•์ธํ•ด ๋ดค๋Š”๋ฐ ์•ˆ ๋น„์Šทํ•ด ๋ณด์ž…๋‹ˆ๋‹ค.


๋‹ค์‹œ ๋Œ์•„์™€์„œ ์ œ๊ฐ€ ๋งŒ๋“  Title ์œ ์ €์ปจํŠธ๋กค์„ ์‹คํ–‰ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

ํ”„๋กœ์ ํŠธ/src/App.js

import React from "react"
import Title from "./Title"

export default function App() {
    return (
        <div>
            <Title/>
        </div>
    );
}

๋ฌผ๋ก  ๋™์ž‘์„ ํ•˜๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•œ ๋งŽ์€ ๋ถ€๋ถ„๋“ค์„ ์€๊ทผ์Šฌ์ฉ ์ƒ๋žตํ–ˆ์ง€๋งŒ,
ํ•ต์‹ฌ์€ script ์ฝ”๋“œ์™€ html์ด ๊ฒฐํ•ฉ๋œ ๊ตฌ์กฐ๋ผ๋Š” ๊ฒƒ์„ ๋‚˜ํƒ€๋‚ด๊ธฐ ์œ„ํ•œ ๋ชฉ์ ์ž…๋‹ˆ๋‹ค.

๋ฆฌ์•กํŠธ ๋ณธ์ธ๋„ ์Šค์Šค๋กœ ์žฌ๋ฏธ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋Š” ๊ฒƒ ๊ฐ™๋„ค์š”.

This funny tag syntax is neither a string nor HTML.
์ด ์žฌ๋ฏธ์žˆ๋Š” ํƒœ๊ทธ ๊ตฌ๋ฌธ์€ ๋ฌธ์ž์—ด๋„ HTML๋„ ์•„๋‹™๋‹ˆ๋‹ค. - ๋ฆฌ์•กํŠธ


๊ณ„์†ํ•ด์„œ ์ฝ”๋“œ๋ฅผ ์‚ดํŽด๋ณด๋ฉด,

์ด๋Ÿฐ ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

import React from "react"
import Title from "./Title"

var element = <h1>hello Dotnet DEV</h1>

export default function App() {
    return (
        <div>
            <Title/>
            {element}
        </div>
    );
}

element ๋ณ€์ˆ˜๋ฅผ ์ž˜ ๋ณด๋ฉด ์ผ๋ฐ˜ string์ด ์•„๋‹ˆ๋ผ <h1/> ๊ทธ ์ž์ฒด์ž…๋‹ˆ๋‹ค.


๊ทธ๋ฆฌ๊ณ  ๋” ์‹ ๊ธฐํ•œ ๊ฒƒ์€,

element๋ฅผ Title์— ๋ณด๋‚ผ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

<Title ele={element}/>

๊ทธ๋Ÿผ,

Title์—์„œ๋Š” ๊ฐ’์„ ์–ด๋–ป๊ฒŒ ๋ฐ›์„๊นŒ์š”?

export default function Title(prop) {
    return (
        <div>
            Dotnet DEV
            {prop.ele}
       </div>
    );
}

์ƒ๊ฐ์ฒ˜๋Ÿผ ์œ ์—ฐํ•˜๊ฒŒ ์ž˜ ๋„˜์–ด๊ฐ‘๋‹ˆ๋‹ค.
๋ณธ๋ฌธ์—์„œ ์–ธ๊ธ‰ ๋“œ๋ฆฐ ๊ฒƒ์ฒ˜๋Ÿผ ๋งŽ์€ ๋ถ€๋ถ„๋“ค์„ ์ƒ๋žตํ•œ ์„ค๋ช…์ธ ์  ์ดํ•ดํ•ด์ฃผ์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค.

๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. :grinning:


๋์œผ๋กœ JSX ์„ค๋ช…๋„ ํ•œ๋ฒˆ ์ฝ์–ด๋ณด์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค.

์™œ JSX์ธ๊ฐ€?

React๋Š” ๋ Œ๋”๋ง ๋กœ์ง์ด ๋ณธ์งˆ์ ์œผ๋กœ ๋‹ค๋ฅธ UI ๋กœ์ง๊ณผ ๊ฒฐํ•ฉ๋˜์–ด ์žˆ๋‹ค๋Š” ์‚ฌ์‹ค์„ ๋ฐ›์•„๋“ค์ž…๋‹ˆ๋‹ค. ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ ๋ฐฉ์‹, ์‹œ๊ฐ„ ๊ฒฝ๊ณผ์— ๋”ฐ๋ฅธ ์ƒํƒœ ๋ณ€๊ฒฝ ๋ฐฉ์‹, ๋ฐ์ดํ„ฐ ํ‘œ์‹œ ์ค€๋น„ ๋ฐฉ์‹ ๋“ฑ์ž…๋‹ˆ๋‹ค.

๋งˆํฌ์—…๊ณผ ๋กœ์ง์„ ๋ณ„๋„์˜ ํŒŒ์ผ์— ๋„ฃ์–ด ์ธ์œ„์ ์œผ๋กœ ๊ธฐ์ˆ  ์„ ๋ถ„๋ฆฌํ•˜๋Š” ๋Œ€์‹  React ๋Š” ๋‘ ๊ฐ€์ง€๋ฅผ ๋ชจ๋‘ ํฌํ•จํ•˜๋Š” "๊ตฌ์„ฑ ์š”์†Œ"๋ผ๊ณ  ํ•˜๋Š” ๋Š์Šจํ•˜๊ฒŒ ๊ฒฐํ•ฉ๋œ ๋‹จ์œ„๋กœ ์šฐ๋ ค ๋ฅผ ๋ถ„๋ฆฌ ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ ์„น์…˜ ์—์„œ ๊ตฌ์„ฑ ์š”์†Œ์— ๋Œ€ํ•ด ๋‹ค์‹œ ๋‹ค๋ฃจ ๊ฒ ์ง€๋งŒ, ์•„์ง JS์— ๋งˆํฌ์—…์„ ๋„ฃ๋Š” ๊ฒƒ์ด ์ต์ˆ™ํ•˜์ง€ ์•Š๋‹ค๋ฉด ์ด ๊ฐ•์—ฐ ์„ ํ†ตํ•ด ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์œผ๋กœ ์„ค๋“ํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

React ๋Š” JSX๋ฅผ ์‚ฌ์šฉํ•  ํ•„์š”๊ฐ€ ์—†์ง€๋งŒ ๋Œ€๋ถ€๋ถ„์˜ ์‚ฌ๋žŒ๋“ค์€ JavaScript ์ฝ”๋“œ ๋‚ด์—์„œ UI๋กœ ์ž‘์—…ํ•  ๋•Œ ์‹œ๊ฐ์  ๋ณด์กฐ ์ˆ˜๋‹จ์œผ๋กœ ๋„์›€์ด ๋œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ React๊ฐ€ ๋” ์œ ์šฉํ•œ ์˜ค๋ฅ˜ ๋ฐ ๊ฒฝ๊ณ  ๋ฉ”์‹œ์ง€๋ฅผ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

JSX ์„ค๋ช… ์›๋ฌธ ๋ณด๊ธฐ

2๊ฐœ์˜ ์ข‹์•„์š”

๋ณต์žกํ•˜๊ณ  ์ง€์ €๋ถ„ํ•œ ํ”„๋กœ์ ํŠธ ์ •๋ฆฌํ•˜๊ธฐ


.vscode/settings.json ํŒŒ์ผ์„ ํ†ตํ•ด ์ œ์™ธํ•  ํด๋” ๋˜๋Š” ํŒŒ์ผ์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์ œ์™ธ ๋Œ€์ƒ์€ ๋ฌผ๋ฆฌ์ ์œผ๋กœ ์ง€์›Œ์ง€๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ vscode ํƒ์ƒ‰๊ธฐ ๋‚ด์—์„œ ๋ณด์ด์ง€ ์•Š๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

ํŠนํžˆ React ํ”„๋กœ์ ํŠธ ๊ตฌ์„ฑ์„ ๋ณด๋ฉดโ€ฆ
๊ฑฐ์˜ ์ง์ ‘ ์‚ฌ์šฉํ•˜์ง€ ์•Š์œผ๋ฉด์„œ ์ƒ์„ฑ๋œ ํด๋”๋‚˜ ํŒŒ์ผ์ด ๋งŽ๊ธฐ ๋•Œ๋ฌธ์— ์—ฌ๊ฐ„ ์‹ ๊ฒฝ์ด ์“ฐ์ž…๋‹ˆ๋‹ค.

์ œ๊ฑฐ ๋ฐฉ๋ฒ• ๋ฐ ๋Œ€์ƒ


์ทจํ–ฅ๋Œ€๋กœ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.
์ €๋Š” node๊ฐ€ ์„ค์น˜๋˜๋Š” ํด๋”์™€ package, .gitignore ๊ฐ™์€ ๊ธฐ๋ณธ ๋ฃจํŠธ์— ๋„๋ถ€๋Ÿฌ์ ธ์žˆ๋Š” ํ•ญ๋ชฉ๋“ค ์œ„์ฃผ๋กœ ์ œ์™ธํ•ฉ๋‹ˆ๋‹ค.

{
    "files.exclude": {
        "**/node_modules": true,
        "**/package.json": true,
        "**/package-lock.json": true,
        "**/.gitignore": true
    }
}

๊ฐ„๋‹จํ•˜๊ฒŒ ์ „๊ณผ ํ›„ ๋น„๊ต ์‚ฌ์ง„๋„ ํ™•์ธํ•ด๋ณผ๊นŒ์š”?

์ œ์™ธ ์ „ ์ œ์™ธ ํ›„
image image

์ด๋Ÿฐ ๋ฐฉ์‹์œผ๋กœ ๊ฐ€๊ฟ”๋‚˜๊ฐ€๋ฉด ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ๋ฅผ ์ž˜ ์ •๋ฆฌํ•ด๊ฐ€๋ฉด์„œ ํ™•์žฅํ•˜๋Š”๋ฐ ํฐ ๋„์›€์ด ๋˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์ฝ์–ด์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. :smile:

2๊ฐœ์˜ ์ข‹์•„์š”

ํด๋ž˜์Šค vs ํ•จ์ˆ˜


๋ฆฌ์—‘ํŠธ๋Š” ํด๋ž˜์Šค์™€ ํ•จ์ˆ˜๋ฅผ ํ†ตํ•œ ๊ฐœ๋ฐœ ๊ตฌ์กฐ ๋ฐฉ์‹์„ ์„ ํƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

:round_pushpin: ๋‘ ๋ฐฉ์‹์€ ๋ฐฉ์‹์ด ๋‹ค๋ฅผ ๋ฟ ๋™์ผํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. (๋ฐฉ์‹์˜ ์ฐจ์ด :laughing:)


ํด๋ž˜์Šค


๋ฆฌ์—‘ํŠธ์—์„œ์˜ ํด๋ž˜์Šค ๋ฐฉ์‹์˜ ๊ฐœ๋ฐœ ๋ฌธ๋ฒ•์€ C#์ด๋‚˜ Java๊ฐ™์€ ๊ฐ์ฒด์ง€ํ–ฅ ๊ฐœ๋ฐœ ๋ฐฉ์‹๊ณผ ์•„์ฃผ ๋น„์Šทํ•ฉ๋‹ˆ๋‹ค. ํŠนํžˆ ๋ฌธ๋ฒ•์ ์œผ๋กœ๋Š” Python๊ณผ๋„ ๊ฑฐ์˜ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ธ์Šคํ„ด์Šค ๊ฐ์ฒด์— ์นœ์ˆ™ํ•œ ๊ฐœ๋ฐœ์ž๋ผ๋ฉด ๋”์šฑ ๋” ์นœ์ˆ™ํ•˜๊ฒŒ ๋‹ค๊ฐ€๊ฐˆ ์ˆ˜ ์žˆ๊ฒ ๋„ค์š”.

:round_pushpin: ํ•˜์ง€๋งŒ ํด๋ž˜์Šค ๋ฐฉ์‹์€ ๋ฆฌ์—‘ํŠธ์˜ ๊ณ ์ „ ๋ฐฉ์‹์ด๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. ์ฐธ๊ณ ๋กœ ์ตœ๊ทผ์˜ ๋ฆฌ์—‘ํŠธ๋Š” ํ•จ์ˆ˜(Functional) ๋ฐฉ์‹ ๊ฐœ๋ฐœ์„ ๋” ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค. ํด๋ž˜์Šค๋Š” ์‚ด์ง๋งŒ ์‚ดํŽด๋ณผ๊ฒŒ์š”!

ํด๋ž˜์Šค ๋ฐฉ์‹์˜ ์ปดํฌ๋„ŒํŠธ ๊ตฌ์กฐ ํ˜•ํƒœ์ž…๋‹ˆ๋‹ค.

class Welcome extends React.Component {
    render() {
        return <h1>Hello, {this.props.name}</h1>;
    }
}

React.Component ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›๋Š” ๊ฒƒ์ด ํด๋ž˜์Šค ๊ธฐ๋ฐ˜์˜ ๊ธฐ๋ณธ ์ปดํฌ๋„ŒํŠธ์˜ ์‹œ์ž‘์ž…๋‹ˆ๋‹ค.

ํ•จ์ˆ˜


ํ•จ์ˆ˜ํ˜•(Functional) ๊ธฐ๋ณธ ์ปดํฌ๋„ŒํŠธ ๊ตฌ์กฐ ํ˜•ํƒœ์ž…๋‹ˆ๋‹ค.

export default JamesButton(props) {
    
    return (
        <div></div>
    );
}

TBDโ€ฆ

[ํŒ] - ๋ฆฌ์—‘ํŠธ์— ๋Œ€ํ•ด ๊ฒ€์ƒ‰ํ•˜๋ฉด ๋ณดํ†ต class ๊ตฌ์กฐ ๋ฐฉ์‹์˜ ์†Œ์Šค์ฝ”๋“œ๋‚˜ ์„ค๋ช…๋“ค์ด ์ฃผ๋กœ ๊ฒ€์ƒ‰๋ฉ๋‹ˆ๋‹ค. ์ด ๋•Œ functional ํ‚ค์›Œ๋“œ๋ฅผ ์ด์šฉํ•˜์—ฌ ๊ฒ€์ƒ‰ํ•˜์‹ ๋‹ค๋ฉด ํ•จ์ˆ˜ํ˜• ๊ฒ€์ƒ‰๊ฒฐ๊ณผ๋ฅผ ์†์‰ฝ๊ฒŒ ์ฐพ์œผ์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

TBDโ€ฆ

1๊ฐœ์˜ ์ข‹์•„์š”