Post

[Day49] React ์„ค์ •(vite) & JSX & props

[Day49] React ์„ค์ •(vite) & JSX & props

๐Ÿ”ธ Vite ๊ธฐ๋ฐ˜ React ์„ค์น˜

React ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ

1
2
3
4
5
6
7
# Vite + React ํ…œํ”Œ๋ฆฟ์œผ๋กœ ์ƒ์„ฑ
npm create vite@latest my-react-app -- --template react
cd my-react-app
npm install

# ๋˜๋Š” ์•„๋ž˜์ฒ˜๋Ÿผ ์ง์ ‘ ํ…œํ”Œ๋ฆฟ ์„ ํƒ
npm create vite

์ œ์‹œ๋œ ์ˆœ์„œ๋Œ€๋กœ ์…‹ํŒ…ํ•œ ๋ชจ์Šต

์ฃผ์˜! ํด๋”๋ช… ์ž‘์„ฑํ•˜์ง€ ์•Š์•„๋„ ๋  ๊ฒฝ์šฐ ( . )

npm install

npm i ํ›„ node_modules, package-lock.json ์ƒ์„ฑ๋จ

React ์•ฑ ์‹คํ–‰

1
npm run dev
  • localhost:5173์—์„œ ์•ฑ ํ™•์ธ ๊ฐ€๋Šฅ
  • vite.config.js์—์„œ ํฌํŠธ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅ

Vite๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ 

  1. ๋น ๋ฅธ ๊ฐœ๋ฐœ ์„œ๋ฒ„
    • Vite๋Š” ๋ฒˆ๋“ค๋ง ์—†์ด ๋„ค์ดํ‹ฐ๋ธŒ ES ๋ชจ๋“ˆ์„ ํ™œ์šฉํ•˜์—ฌ ๋งค์šฐ ๋น ๋ฅธ ๊ฐœ๋ฐœ ์„œ๋ฒ„๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ์กด์˜ webpack ๊ธฐ๋ฐ˜ ๋„๊ตฌ(create-react-app)๋ณด๋‹ค ํ›จ์”ฌ ๋น ๋ฅด๊ฒŒ ์‹œ์ž‘๋ฉ๋‹ˆ๋‹ค.
  2. ๋น ๋ฅธ ํ•ซ ๋ชจ๋“ˆ ๊ต์ฒด(HMR)
    • ์ฝ”๋“œ๋ฅผ ๋ณ€๊ฒฝํ•  ๋•Œ ํŽ˜์ด์ง€๊ฐ€ ๊ฑฐ์˜ ์ฆ‰์‹œ ์—…๋ฐ์ดํŠธ๋˜์–ด ๊ฐœ๋ฐœ ๊ฒฝํ—˜์ด ํฌ๊ฒŒ ํ–ฅ์ƒ๋ฉ๋‹ˆ๋‹ค.
  3. ์ตœ์ ํ™”๋œ ๋นŒ๋“œ : ํ”„๋กœ๋•์…˜ ๋นŒ๋“œ ์‹œ Rollup์„ ์‚ฌ์šฉํ•˜์—ฌ ์ตœ์ ํ™”๋œ ๊ฒฐ๊ณผ๋ฌผ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  4. ๊ฐ„์†Œํ™”๋œ ์„ค์ •
    • ๊ธฐ๋ณธ ์„ค์ •์ด ์ž˜ ๋˜์–ด ์žˆ์–ด ์ถ”๊ฐ€ ๊ตฌ์„ฑ ์—†์ด๋„ ๋ฐ”๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  5. TypeScript ๋ฐ JSX ๊ธฐ๋ณธ ์ง€์›
    • ๋ณ„๋„์˜ ์„ค์ • ์—†์ด TypeScript์™€ JSX๋ฅผ ์ฆ‰์‹œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  6. ๋‹ค์–‘ํ•œ ํ”„๋ ˆ์ž„์›Œํฌ ํ…œํ”Œ๋ฆฟ
    • React ์™ธ์—๋„ Vue, Preact, Lit ๋“ฑ ๋‹ค์–‘ํ•œ ํ”„๋ ˆ์ž„์›Œํฌ ํ…œํ”Œ๋ฆฟ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.
  7. ๊ฐ€๋ฒผ์šด ์˜์กด์„ฑ : create-react-app์— ๋น„ํ•ด ์˜์กด์„ฑ์ด ์ ์–ด ์„ค์น˜ ํฌ๊ธฐ๊ฐ€ ์ž‘์Šต๋‹ˆ๋‹ค.
  8. ์ตœ์‹  ์›น ํ‘œ์ค€ ํ™œ์šฉ : ES ๋ชจ๋“ˆ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜์—ฌ ์ตœ์‹  ์›น ํ‘œ์ค€์„ ์ ๊ทน ํ™œ์šฉํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ“ Vite Scaffolding ๊ตฌ์กฐ

ํด๋”/ํŒŒ์ผ์„ค๋ช…
node_modules์˜์กด์„ฑ ๋ชจ์Œ
public์ •์  ํŒŒ์ผ ํด๋”
src๊ฐœ๋ฐœ ์†Œ์Šค ์ฝ”๋“œ ํด๋”
โ”” assets์ด๋ฏธ์ง€, ํฐํŠธ ๋“ฑ ์ •์  ์ž์‚ฐ
index.html์ง„์ž… HTML ํŒŒ์ผ
main.jsxReact ์•ฑ ์ง„์ž…์ 
App.jsx / App.css์ฃผ์š” ์ปดํฌ๋„ŒํŠธ ๋ฐ ์Šคํƒ€์ผ
index.css์ „์—ญ ์Šคํƒ€์ผ
package.jsonํ”„๋กœ์ ํŠธ ์„ค์ • ๋ฐ ์Šคํฌ๋ฆฝํŠธ
eslint.config.js์ตœ์‹  ํ”Œ๋žซ ESLint ๊ตฌ์„ฑ
vite.config.jsVite ๋นŒ๋“œ ์„ค์ •
.gitignore / README.md๋ฒ„์ „ ๊ด€๋ฆฌ ๋ฐ ๋ฌธ์„œ

ESLint + Prettier ์„ค์ •

1. ESLint ์„ค์ • (ํ”Œ๋žซ ๊ตฌ์„ฑ: eslint.config.js)

์ฝ”๋“œ ํ’ˆ์งˆ๊ณผ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•œ ์ค‘์š”ํ•œ ์„ค์ • ํŒŒ์ผ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import js from '@eslint/js';
import globals from 'globals';
import reactHooks from 'eslint-plugin-react-hooks';
import reactRefresh from 'eslint-plugin-react-refresh';
import prettier from 'eslint-plugin-prettier';
import prettierConfig from 'eslint-config-prettier';

export default [
  { ignores: ['dist'] },
  prettierConfig, // ESLint์™€ Prettier ์ถฉ๋Œ ๋ฐฉ์ง€
  {
    files: ['**/*.{js,jsx}'],
    languageOptions: {
      ecmaVersion: 2020,
      globals: globals.browser,
      parserOptions: {
        ecmaVersion: 'latest',
        ecmaFeatures: { jsx: true },
        sourceType: 'module',
      },
    },
    plugins: {
      'react-hooks': reactHooks,
      'react-refresh': reactRefresh,
      prettier: prettier, // Prettier ํ”Œ๋Ÿฌ๊ทธ์ธ ์ถ”๊ฐ€
    },
    rules: {
      ...js.configs.recommended.rules,
      ...reactHooks.configs.recommended.rules,
      'prettier/prettier': 'error', // Prettier ๊ทœ์น™ ์œ„๋ฐ˜ ์‹œ ์—๋Ÿฌ ํ‘œ์‹œ
      'no-unused-vars': ['error', { varsIgnorePattern: '^[A-Z_]' }],
      'react-refresh/only-export-components': ['warn', { allowConstantExport: true }],
    },
  },
];

๐Ÿ“Œ ํ”Œ๋žซ ๊ตฌ์„ฑ ๋ฐฉ์‹: React 19 ์ด์ƒ์—์„œ๋Š” .eslintrc ๋Œ€์‹  eslint.config.js๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๊ถŒ์žฅ๋จ.


2. Prettier ์„ค์ • (.prettierrc)

Prettier๋Š” ์ฝ”๋“œ์˜ ์Šคํƒ€์ผ๊ณผ ํฌ๋งท์„ ์ผ๊ด€๋˜๊ฒŒ ์œ ์ง€ํ•˜๋Š” ๋ฐ ์ค‘์ 

1
2
3
4
5
6
7
8
9
10
{
  "semi": false,
  "singleQuote": true,
  "tabWidth": 2,
  "trailingComma": "es5",
  "printWidth": 100,
  "bracketSpacing": true,
  "arrowParens": "avoid",
  "endOfLine": "auto"
}

3. eslint-plugin-prettier์™€ ๊ด€๋ จ๋œ ๋‹ค๋ฅธ ํ•„์š”ํ•œ ํŒจํ‚ค์ง€๋“ค์„ ์„ค์น˜

ํ†ตํ•ฉ ํ”Œ๋Ÿฌ๊ทธ์ธ์ด ์ถฉ๋Œ ์—†์ด ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ด์คŒ

1
npm install --save-dev eslint prettier eslint-plugin-prettier eslint-config-prettier

4. VS Code Workspace ์„ค์ • (.vscode/settings.json)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
  "editor.formatOnSave": true,
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "[javascript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[javascriptreact]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "explorer.fileNesting.enabled": true,
  "explorer.fileNesting.patterns": {
    "package.json": ".gitignore, .prettierrc, eslint.config.js, package-lock.json, vite.config.js"
  }
}

์œ„ ์ฝ”๋“œ์—์„œ ์ด ๋ถ€๋ถ„์€

1
2
3
4
"explorer.fileNesting.enabled": true,
"explorer.fileNesting.patterns": {
  "package.json": ".gitignore, .prettierignore, .prettierrc, eslint.config.js, package-lock.json, vite.config.js"
}
  • setting.json์—์„œ ํด๋” ๊ตฌ์กฐ๋กœ ๋ฌถ์–ด์„œ ๋งŒ๋“ค์–ด์ค˜ ~ ๋ผ๋Š” ๋œป์˜ ์ฝ”๋“œ
  • package.json์„ ๊ธฐ์ค€์œผ๋กœ ๊ด€๋ จ ์„ค์ • ํŒŒ์ผ๋“ค์„ ํ•˜๋‚˜๋กœ ๋ฌถ์–ด์„œ ๋ณด์—ฌ์คŒ


package.json์ด ํด๋” ๊ตฌ์กฐ๋กœ ๋ฐ”๋€ ๋ชจ์Šต

5. Prettier ๋ฌด์‹œ ํŒŒ์ผ (.prettierignore)

1
2
3
4
node_modules
dist
build
.vscode

6. package.json ์Šคํฌ๋ฆฝํŠธ ์ถ”๊ฐ€

1
2
3
4
5
6
7
"scripts": {
  "dev": "vite",
  "build": "vite build",
  "lint": "eslint . --config eslint.config.js --fix",
  "format": "prettier --write \"src/**/*.{js,jsx,css,json}\"",
  "preview": "vite preview"
}

โœ… ์„ค์ • ํ™•์ธ

1
2
3
npm run lint     # ESLint ํ™•์ธ
npm run format   # Prettier ํฌ๋งทํŒ… ํ™•์ธ
npm run dev      # ํ”„๋กœ์ ํŠธ ์‹คํ–‰

๐Ÿ”ธ ์‹ค์Šต

์ปดํฌ๋„ŒํŠธ ๊ตฌ์กฐ ๋ถ„๋ฆฌ

1
2
3
4
5
App
 โ”œโ”€โ”€ Header
 โ”œโ”€โ”€ InputFiled
 โ””โ”€โ”€ PostList
       โ””โ”€โ”€ List

CSS ๊ธฐ์ค€ ์„ค์ • (์ „์—ญ ๋ณ€์ˆ˜)

  • :root์— ๋ณ€์ˆ˜ ์„ ์–ธํ•˜์—ฌ ํ…Œ๋งˆ ์ƒ‰์ƒ ๋ฐ ๊ณตํ†ต ์†์„ฑ์„ ๊ด€๋ฆฌ
  • ์œ ์ง€๋ณด์ˆ˜ ์šฉ์ดํ•˜๊ณ , ์ผ๊ด€๋œ ๋””์ž์ธ ๊ตฌํ˜„ ๊ฐ€๋Šฅ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
:root {
  font-family: 'S-CoreDream-3Light';
  --blue-dark: #1e6f9f;
  --blue: #4ea8de;
  --purple-dark: #5e60ce;
  --purple: #8284fa;
  --gray-700: #0d0d0d;
  --gray-600: #1a1a1a;
  --gray-500: #262626;
  --gray-400: #333333;
  --gray-300: #808080;
  --gray-200: #d9d9d9;
  --gray-100: #f2f2f2;
  --danger: #e25858;
  --gap1: 8px;
  --gap2: 16px;
  --gap3: 32px;
  line-height: 1.4;
  color: var(--gray-100);
}

์‚ฌ์šฉ ์˜ˆ์‹œ

1
2
3
body {
  background-color: var(--gray-600);
}

Props๋กœ ๋ฐ์ดํ„ฐ ์ „๋‹ฌ

  • props๋ฅผ ํ†ตํ•ด ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ž์‹ ์ปดํฌ๋„ŒํŠธ์— ์ „๋‹ฌ
  • ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ์—์„œ ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ๋กœ๋งŒ ํ๋ฅด๋ฉฐ, ๋‹จ๋ฐฉํ–ฅ ๋ฐ์ดํ„ฐ ํ๋ฆ„์„ ์œ ์ง€ํ•œ๋‹ค.

๊ตฌ์กฐ ๋ถ„ํ•ด ํ• ๋‹น

  • ๋” ๊ฐ„๊ฒฐํ•˜๊ณ  ์ง๊ด€์ ํ•˜๊ฒŒ props๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.
  • ์ปดํฌ๋„ŒํŠธ ์„ ์–ธ ์‹œ ๊ด„ํ˜ธ ์•ˆ์—์„œ props๋ฅผ ๊ตฌ์กฐ ๋ถ„ํ•ดํ•˜์—ฌ ๋ฐ”๋กœ ์‚ฌ์šฉ.

๊ธฐ์กด ์‚ฌ์šฉ ๋ฐฉ์‹

1
2
3
const PostList = (props) => {
  return <List area={props.data[0]} />
}

๊ตฌ์กฐ ๋ถ„ํ•ด ํ• ๋‹น ๋ฐฉ์‹

1
2
3
4
5
6
7
8
9
const PostList = ({ data }) => {
  return (
    <>
      {data.map((area, i) => (
        <List key={i} area={area} />
      ))}
    </>
  )
}
1
2
3
const List = ({ area }) => {
  return <p>{area}</p>
}

๊ตฌ์กฐ ๋ถ„ํ•ด ํ• ๋‹น์„ ํ™œ์šฉํ•˜๋ฉด ์ฝ”๋“œ์˜ ๊ฐ€๋…์„ฑ์ด ํ–ฅ์ƒ๋˜๊ณ , props.area์ฒ˜๋Ÿผ ์ผ์ผ์ด ์ ‘๊ทผํ•˜์ง€ ์•Š์•„๋„ ๋˜์–ด ํŽธ๋ฆฌํ•˜๋‹ค!


props ์ฝ”๋“œ ํ๋ฆ„

App.js

๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ •์˜ํ•˜๊ณ , ์ž์‹(PostList)์— ์ „๋‹ฌ

1
2
3
const list = ['์†ก๋„', '์ธ์ฒœ', '์„œ์šธ', '๋ถ€์‚ฐ', '๋Œ€๊ตฌ', '๋Œ€์ „', '๊ด‘์ฃผ']
const [data, setData] = useState(list)
<PostList data={data} />

PostList.js

props๋กœ ๋ฐ›์€ data๋ฅผ .map()์œผ๋กœ ์ˆœํšŒํ•˜๋ฉฐ List ์ปดํฌ๋„ŒํŠธ์— ์ „๋‹ฌ

1
2
3
{data.map((area, i) => (
  <List key={i} area={area} />
))}

List.js

์ „๋‹ฌ๋ฐ›์€ area๋ฅผ ์ถœ๋ ฅ

1
const List = ({ area }) => <p>{area}</p>

์ปดํฌ๋„ŒํŠธ ๋ถ„๋ฆฌ ๊ตฌ์กฐ

์‹ค์Šต UI

โœ… ๋ฆฌ์ŠคํŠธ ๋ Œ๋”๋ง + ์Šคํƒ€์ผ๋ง + ์•„์ด์ฝ˜ (์‚ญ์ œ ๋ฒ„ํŠผ ๋“ฑ)

[github]React-vite ์‹ค์Šต


๐Ÿ”ธ JS ๋ฉ”๋ชจ๋ฆฌ ์ €์žฅ ๋ฐฉ์‹

Javascript๋Š” ๋™์  ํƒ€์ž… ์–ธ์–ด๋กœ, ๋ณ€์ˆ˜์˜ ํƒ€์ž…์€ ํ”„๋กœ๊ทธ๋žจ์ด ์‹คํ–‰๋˜๋Š” ๋™์•ˆ ๊ฒฐ์ •๋˜๊ณ  ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ๋‹ค. ์ด ์–ธ์–ด์—์„œ์˜ ์ž๋ฃŒํ˜•์œผ๋กœ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์›์‹œ ํƒ€์ž…๊ณผ ๊ฐ์ฒด ํƒ€์ž…์˜ ๋‘ ๊ฐ€์ง€ ๋ฐ์ดํ„ฐ ํƒ€์ž…์ด ์ œ๊ณต๋œ๋‹ค.

์›์‹œ ํƒ€์ž… (Primitive Types)

  • ์›์‹œ ํƒ€์ž…์€ ๊ธฐ๋ณธ์ ์ธ ๋ฐ์ดํ„ฐ ํƒ€์ž…
  • ๋ณ€๊ฒฝ ๋ถˆ๊ฐ€๋Šฅํ•œ ๊ฐ’(immutable values)์„ ์˜๋ฏธ
  • ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ์›์‹œ ํƒ€์ž…์—๋Š” ์—ฌ์„ฏ ๊ฐ€์ง€๊ฐ€ ์žˆ๋‹ค.

    1. Number: ๋ชจ๋“  ์ข…๋ฅ˜์˜ ์ˆซ์ž๋ฅผ ํฌํ•จํ•œ๋‹ค.
    2. String: ํ…์ŠคํŠธ ๋ฐ์ดํ„ฐ๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค.
    3. Boolean: ์ฐธ(true) ๋˜๋Š” ๊ฑฐ์ง“(false) ๊ฐ’์„ ๊ฐ€์ง„๋‹ค.
    4. Undefined: ์ •์˜๋˜์ง€ ์•Š์€ ๊ฐ’์ด๋‹ค.
    5. Null: ์˜๋„์ ์œผ๋กœ ๋น„์–ด ์žˆ๋Š” ๊ฐ’์„ ๋‚˜ํƒ€๋‚ธ๋‹ค.
    6. Symbol: ES6์—์„œ ๋„์ž…๋œ ๊ณ ์œ ํ•˜๊ณ  ๋ณ€๊ฒฝ ๋ถˆ๊ฐ€๋Šฅํ•œ ๋ฐ์ดํ„ฐ ํƒ€์ž…์ด๋‹ค.

๊ฐ์ฒด ํƒ€์ž… (Object Types)

  • ์›์‹œ ํƒ€์ž…์„ ์ œ์™ธํ•œ ๋ชจ๋“  ์ž๋ฃŒํ˜•์ด ๊ฐ์ฒด ํƒ€์ž…
  • ๊ฐ์ฒด ํƒ€์ž…์€ ์›์‹œ ํƒ€์ž…๊ณผ ๋‹ฌ๋ฆฌ ๋ณต์žกํ•œ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ฅผ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๊ฐ์ฒด๋Š” ํ”„๋กœํผํ‹ฐ(์†์„ฑ)์˜ ์ง‘ํ•ฉ์œผ๋กœ, ๊ฐ ํ”„๋กœํผํ‹ฐ๋Š” ํ‚ค์™€ ๊ฐ’์œผ๋กœ ๊ตฌ์„ฑ๋œ๋‹ค.
  • ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ๋Š” ํ•จ์ˆ˜๋„ ๊ฐ์ฒด์˜ ํ•œ ํ˜•ํƒœ๋กœ ๊ฐ„์ฃผํ•œ๋‹ค.
  1. Object: ํ‚ค(Key)์™€ ๊ฐ’(Value)์„ ๊ฐ€์ง„ ํ”„๋กœํผํ‹ฐ์˜ ์ปฌ๋ ‰์…˜์ด๋‹ค.
  2. Array: ์ˆœ์„œ๊ฐ€ ์žˆ๋Š” ๊ฐ’์˜ ์ง‘ํ•ฉ์ด๋‹ค.
  3. Function: ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ ์ฝ”๋“œ ๋ธ”๋ก์ด๋‹ค.
  4. Date, RegExp ๋“ฑ์˜ ๋‚ด์žฅ ๊ฐ์ฒด๋“ค๋„ ์žˆ๋‹ค.

์›์‹œ ํƒ€์ž…๊ณผ ๊ฐ์ฒด ํƒ€์ž…์˜ ์ฐจ์ด

ํ•ญ๋ชฉ์›์‹œ ํƒ€์ž… (Primitive)๊ฐ์ฒด ํƒ€์ž…(Object)
์ €์žฅ ๋ฐฉ์‹๊ฐ’ ์ž์ฒด๊ฐ€ ๋ณ€์ˆ˜์— ์ง์ ‘ ์ €์žฅ๋จ๋ฉ”๋ชจ๋ฆฌ์— ๊ฐ์ฒด๊ฐ€ ์ €์žฅ๋˜๊ณ  ๋ณ€์ˆ˜๋Š” ๊ทธ ์ฐธ์กฐ(์ฃผ์†Œ)๋ฅผ ์ €์žฅ
๋ถˆ๋ณ€์„ฑ๋ถˆ๋ณ€(Immutable) โ€“ ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋ฉด ์ƒˆ ๊ฐ’์ด ํ• ๋‹น๋จ๊ฐ€๋ณ€(Mutable) โ€“ ๊ฐ์ฒด์˜ ์†์„ฑ์€ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅ
๋น„๊ต ๋ฐฉ์‹๊ฐ’ ๋น„๊ต (===๋Š” ๊ฐ’์ด ๊ฐ™์œผ๋ฉด true)์ฐธ์กฐ ๋น„๊ต (===๋Š” ๋™์ผ ๊ฐ์ฒด์ผ ๋•Œ๋งŒ true)
๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ๊ณ ์ •๋œ ํฌ๊ธฐ, ๊ด€๋ฆฌ๊ฐ€ ๋‹จ์ˆœํฌ๊ธฐ๊ฐ€ ๊ฐ€๋ณ€์ , ๋™์ ์œผ๋กœ ๊ด€๋ฆฌ
๋ณต์‚ฌ ๋ฐฉ์‹๊ฐ’ ๋ณต์‚ฌ (๊นŠ์€ ๋ณต์‚ฌ)์ฐธ์กฐ ๋ณต์‚ฌ (์–•์€ ๋ณต์‚ฌ)
์ €์žฅ ์œ„์น˜StackHeap
์„ฑ๋Šฅ ์ธก๋ฉด๋” ๋น ๋ฆ„ (๊ฐ€๋ณ๊ณ  ์Šคํƒ์— ์ €์žฅ๋จ)๋” ๋А๋ฆผ (ํž™ ์ ‘๊ทผ + ์ฐธ์กฐ ๊ตฌ์กฐ ๋•Œ๋ฌธ)

๐Ÿ’ก ๊ฐ์ฒด, ๋ฐฐ์—ด, ํ•จ์ˆ˜ ๋“ฑ์€ ์ „๋ถ€ ์ฐธ์กฐ ํƒ€์ž…์ด๋ฉฐ, ๋ณ€์ˆ˜๋Š” ์‹ค์ œ ๊ฐ’์ด ์•„๋‹Œ Heap ์ฃผ์†Œ๋ฅผ ์ฐธ์กฐํ•œ๋‹ค.

์˜ˆ์ œ

1
2
3
4
5
6
7
8
9
10
11
12
13
// ์›์‹œ ํƒ€์ž…
let num1 = 100;
let num2 = num1;

num2 = 200;
console.log(num1); // 100. ์›๋ณธ ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์Œ
console.log(num2); // 200

// ๊ฐ์ฒด ํƒ€์ž…
let obj1 = { value: 100 };
let obj2 = obj1;
obj2.value = 200;
console.log(obj1.value, obj2.value); // 200, 200. ์ฐธ์กฐ๋œ ๊ฐ์ฒด์ž์ฒด๊ฐ€ ๋ณ€๊ฒฝ๋จ. (๊ฐ™์€ ๋ฉ”๋ชจ๋ฆฌ ์ฃผ์†Œ๋ฅผ ๊ณต์œ )

๐Ÿ”ธ ๋ณต์Šต

โœ… jsx์™€ js๋Š” ์™œ ๊ตฌ๋ณ„ํ•ด์„œ ์‚ฌ์šฉํ•˜๋Š”๊ฐ€?

ํŒŒ์ผ ํ™•์žฅ์ž ๊ตฌ๋ถ„์˜ ์ฃผ์š” ์ด์œ 

  1. ๋ช…ํ™•ํ•œ ์˜๋„ ์ „๋‹ฌ
    • .jsx: React ์ปดํฌ๋„ŒํŠธ, UI ๊ด€๋ จ ์š”์†Œ ํฌํ•จ
    • .js: ์ผ๋ฐ˜ JavaScript ๋กœ์ง, ์œ ํ‹ธ ํ•จ์ˆ˜ ๋“ฑ ๋‹ด๋‹น
  2. ๋„๊ตฌ ๋ฐ ํŽธ์ง‘๊ธฐ ์ตœ์ ํ™”
    • ํŽธ์ง‘๊ธฐ(VS Code ๋“ฑ)๊ฐ€ ํŒŒ์ผ ์œ ํ˜•์— ๋งž๋Š” ๋ฌธ๋ฒ• ๊ฐ•์กฐ์™€ ์ž๋™ ์™„์„ฑ ๊ธฐ๋Šฅ์„ ์ œ๊ณต
    • JSX ์Šค๋‹ˆํŽซ๊ณผ React ์ž๋™์™„์„ฑ ์ง€์›
  3. ๋นŒ๋“œ ์‹œ์Šคํ…œ ์ตœ์ ํ™”
    • ์›นํŒฉ์ด๋‚˜ Babel ๊ฐ™์€ ๋นŒ๋“œ ๋„๊ตฌ๊ฐ€ ํŒŒ์ผ ์œ ํ˜•์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ์ฒ˜๋ฆฌ
    • JSX ํŒŒ์ผ๋งŒ React ๋ณ€ํ™˜ ๊ณผ์ •์„ ๊ฑฐ์น˜๋„๋ก ์„ค์ •ํ•  ์ˆ˜ ์žˆ์–ด ๋นŒ๋“œ ์„ฑ๋Šฅ ํ–ฅ์ƒ
  4. ์ฝ”๋“œ๋ฒ ์ด์Šค ๊ตฌ์„ฑ์˜ ๋ช…ํ™•์„ฑ
    • ํŒ€์› ๊ฐ„ ํŒŒ์ผ์˜ ์—ญํ• ์„ ์‰ฝ๊ฒŒ ์ดํ•ด
    • ๋Œ€๊ทœ๋ชจ ํ”„๋กœ์ ํŠธ์—์„œ ํŒŒ์ผ์˜ ๋ชฉ์ ์„ ์‰ฝ๊ฒŒ ํŒŒ์•…
  5. ๊ด€์‹ฌ์‚ฌ์˜ ๋ถ„๋ฆฌ (Separation of Concerns)
    • UI ๋กœ์ง(JSX)๊ณผ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง(JS)์„ ๋ถ„๋ฆฌํ•˜์—ฌ ์ฝ”๋“œ ์œ ์ง€๋ณด์ˆ˜์„ฑ ํ–ฅ์ƒ
    • UI(JSX)์™€ ๋กœ์ง(JS)๋ฅผ ๋ถ„๋ฆฌํ•ด ๋‹จ์ผ ์ฑ…์ž„ ์›์น™(SRP) ์‹คํ˜„

React ์—์„œ๋Š” ๋‘ ํ™•์žฅ์ž ๋ชจ๋‘ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋ฉฐ, ๊ธฐ์ˆ ์ ์œผ๋กœ๋Š” ๋™์ผํ•˜๊ฒŒ ์ž‘๋™ํ•œ๋‹ค.
์ด๋Š” ๊ฐœ๋ฐœ์ž์™€ ํŒ€์˜ ์ฝ”๋“œ ๊ตฌ์„ฑ ์„ ํ˜ธ๋„์— ๋”ฐ๋ฅธ ์ปจ๋ฒค์…˜์˜ ๋ฌธ์ œ์ด์ง€๋งŒ, ๋ช…ํ™•ํ•œ ๊ตฌ๋ถ„์€ ๋Œ€๊ทœ๋ชจ ํ”„๋กœ์ ํŠธ์—์„œ ํŠนํžˆ ์œ ์šฉ !


โœ… JSX ๋ฌธ๋ฒ• ์š”์•ฝ

JSX: JavaScript + XML
HTML๊ณผ ๋น„์Šทํ•œ ๋ฌธ๋ฒ•์œผ๋กœ React UI ๊ตฌ์„ฑ์„ ์„ ์–ธ์ ์œผ๋กœ ํ‘œํ˜„

1. ๊ธฐ๋ณธ ๊ตฌ์กฐ : HTML์ฒ˜๋Ÿผ ํƒœ๊ทธ๋ฅผ ์‚ฌ์šฉ

1
const element = <h1>์•ˆ๋…•ํ•˜์„ธ์š”, React!</h1>;

2. JavaScript ํ‘œํ˜„์‹ ์‚ฌ์šฉ

์ค‘๊ด„ํ˜ธ {}๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ JavaScript ํ‘œํ˜„์‹์„ ๋„ฃ์„ ์ˆ˜ ์žˆ์Œ

1
2
const name = 'ํ™๊ธธ๋™';
const element = <h1>์•ˆ๋…•ํ•˜์„ธ์š”, {name}๋‹˜!</h1>;

3. ์†์„ฑ(Attributes) ์ง€์ • - camelCase

1
2
3
4
5
6
// className (class ๋Œ€์‹ )
const element = <div className="container">๋‚ด์šฉ</div>;

// style ๊ฐ์ฒด๋กœ ์ง€์ •
const style = { color: 'blue', fontSize: '16px' };
const element = <p style={style}>์Šคํƒ€์ผ ์ ์šฉ ํ…์ŠคํŠธ</p>;

4. ์ž์‹ ์š”์†Œ ํฌํ•จ

1
2
3
4
5
6
const element = (
  <div>
    <h1>์ œ๋ชฉ</h1>
    <p>๋‚ด์šฉ ์„ค๋ช…</p>
  </div>
);

5. ๋‹ซ๋Š” ํƒœ๊ทธ ํ•„์ˆ˜

1
2
const input = <input type="text" />;
const img = <img src="image.jpg" alt="์ด๋ฏธ์ง€" />;

6. ์กฐ๊ฑด๋ถ€ ๋ Œ๋”๋ง

1
2
3
4
5
// ์‚ผํ•ญ ์—ฐ์‚ฐ์ž ์‚ฌ์šฉ
const element = <div>{isLoggedIn ? <UserGreeting /> : <GuestGreeting />}</div>;

// AND ์—ฐ์‚ฐ์ž ์‚ฌ์šฉ (์กฐ๊ฑด์ด ์ฐธ์ผ ๋•Œ๋งŒ ๋ Œ๋”๋ง)
const element = <div>{unreadMessages.length > 0 && <MessageAlert />}</div>;

7. ๋ฆฌ์ŠคํŠธ ๋ Œ๋”๋ง - map ํ•จ์ˆ˜๋กœ ์ˆœํšŒ

1
2
3
4
5
6
7
8
const numbers = [1, 2, 3, 4, 5];
const listItems = (
  <ul>
    {numbers.map((number) => (
      <li key={number}>{number}</li>
    ))}
  </ul>
);
  • key๋Š” ๊ผญ ๋„ฃ์–ด์•ผ ํ•จ! (React์˜ diff ์„ฑ๋Šฅ ํ–ฅ์ƒ)

8. Fragment ์‚ฌ์šฉ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// <React.Fragment> ์‚ฌ์šฉ
const element = (
  <React.Fragment>
    <h1>์ œ๋ชฉ</h1>
    <p>๋‚ด์šฉ</p>
  </React.Fragment>
);

// ์ถ•์•ฝํ˜• ์‚ฌ์šฉ
const element = (
  <>
    <h1>์ œ๋ชฉ</h1>
    <p>๋‚ด์šฉ</p>
  </>
);

9. ์ด๋ฒคํŠธ ํ•ธ๋“ค๋ง - camelCase

1
2
3
4
5
function handleClick() {
  alert('๋ฒ„ํŠผ์ด ํด๋ฆญ๋˜์—ˆ์Šต๋‹ˆ๋‹ค!');
}

const button = <button onClick={handleClick}>ํด๋ฆญํ•˜์„ธ์š”</button>;

โœ… javascript ํ‘œํ˜„์‹

1. ๋ณ€์ˆ˜ ์ฐธ์กฐ

1
2
let name = 'ํ™๊ธธ๋™';
console.log(name); // ๋ณ€์ˆ˜ name์€ ํ‘œํ˜„์‹

2. ์‚ฐ์ˆ  ํ‘œํ˜„์‹

1
2
3
let sum = 10 + 5; // 10 + 5๋Š” 15๋ผ๋Š” ๊ฐ’์„ ๋งŒ๋“œ๋Š” ํ‘œํ˜„์‹
let product = 4 * 3;

3. ๋ฌธ์ž์—ด ํ‘œํ˜„์‹

1
2
let greeting = 'Hello ' + 'World'; // ๋ฌธ์ž์—ด ์—ฐ๊ฒฐ
let name = `User: ${firstName}`; // ํ…œํ”Œ๋ฆฟ ๋ฆฌํ„ฐ๋Ÿด

4. ๋…ผ๋ฆฌ ํ‘œํ˜„์‹

1
2
let isValid = age > 18 && hasPermission; // ๋…ผ๋ฆฌ ์—ฐ์‚ฐ
let canAccess = isAdmin || isManager; // true/false ๊ฐ’ ์ƒ์„ฑ

5. ํ•จ์ˆ˜ ํ˜ธ์ถœ

1
2
Math.random(); // ํ•จ์ˆ˜ ํ˜ธ์ถœ ์ž์ฒด๊ฐ€ ํ‘œํ˜„์‹
console.log('Hello'); // ํ‘œํ˜„์‹

6. ๊ฐ์ฒด/๋ฐฐ์—ด ๋ฆฌํ„ฐ๋Ÿด

1
2
3
const person = { name: '๊น€์ฒ ์ˆ˜', age: 30 }; // ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด
const numbers = [1, 2, 3, 4]; // ๋ฐฐ์—ด ๋ฆฌํ„ฐ๋Ÿด

7. ์‚ผํ•ญ ์—ฐ์‚ฐ์ž

1
let status = age >= 18 ? '์„ฑ์ธ' : '๋ฏธ์„ฑ๋…„์ž';

8. ํ™”์‚ดํ‘œ ํ•จ์ˆ˜

1
const double = x => x * 2;

โœ… JSX์—์„œ์˜ JavaScript ํ‘œํ˜„์‹

JSX์—์„œ๋Š” ์ค‘๊ด„ํ˜ธ {}๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ JavaScript ํ‘œํ˜„์‹์„ ์‚ฝ์ž…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const name = 'ํ™๊ธธ๋™';
const age = 25;
const isAdmin = true;

// JSX ๋‚ด ํ‘œํ˜„์‹ ์‚ฌ์šฉ ์˜ˆ์‹œ
const element = (
  <div>
    <h1>{name}์˜ ํ”„๋กœํ•„</h1>
    <p>๋‚˜์ด: {age}์„ธ</p>
    <p>์ง์—…: {age >= 18 ? '๊ฐœ๋ฐœ์ž' : 'ํ•™์ƒ'}</p>
    <p>{isAdmin && '๊ด€๋ฆฌ์ž ๊ถŒํ•œ์ด ์žˆ์Šต๋‹ˆ๋‹ค'}</p>
    <p>1๋…„ ํ›„ ๋‚˜์ด: {age + 1}์„ธ</p>
    <p>๋žœ๋ค ID: {Math.floor(Math.random() * 100)}</p>
  </div>
);

JSX ์ค‘๊ด„ํ˜ธ ์•ˆ์—๋Š” ๋ชจ๋“  JavaScript ํ‘œํ˜„์‹์„ ๋„ฃ์„ ์ˆ˜ ์žˆ๋‹ค. ๋‹จ, if ๋ฌธ์ด๋‚˜ for ๋ฃจํ”„์™€ ๊ฐ™์€ ๋ฌธ์žฅ(statements)์€ ํ‘œํ˜„์‹์ด ์•„๋‹ˆ๋ฏ€๋กœ ์ง์ ‘ ๋„ฃ์„ ์ˆ˜ ์—†๋‹ค.

โœ… useState()

  • React์˜ ๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ธ Hook
  • ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ์—์„œ ์ƒํƒœ(state)๋ฅผ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์คŒ
1
2
3
4
5
6
7
8
9
10
11
12
13
import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>ํ˜„์žฌ ์นด์šดํŠธ: {count}</p>
      <button onClick={() => setCount(count + 1)}>์ฆ๊ฐ€</button>
    </div>
  );
}

  1. useState(0)์€ ์ดˆ๊ธฐ๊ฐ’์ด 0์ธ ์ƒํƒœ๋ฅผ ์ƒ์„ฑ
  2. count๋Š” ํ˜„์žฌ ์ƒํƒœ๊ฐ’์„ ์ €์žฅ
  3. setCount๋Š” count์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.

์ฃผ์š” ํŠน์ง•

  • ์ƒํƒœ ๋ณ€๊ฒฝ ์‹œ ์ž๋™ ๋ฆฌ๋ Œ๋”๋ง
  • ์ด์ „ ์ƒํƒœ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์—…๋ฐ์ดํŠธ ์‹œ ํ•จ์ˆ˜ํ˜• ์‚ฌ์šฉ: setCount(prev => prev + 1)
  • ๊ฐ์ฒด ์ƒํƒœ ๊ด€๋ฆฌ ์‹œ ์ „์ฒด ๊ฐ์ฒด๋ฅผ ๋ณต์‚ฌํ•˜์—ฌ ์—…๋ฐ์ดํŠธ
1
2
const [user, setUser] = useState({ name: 'ํ™๊ธธ๋™', age: 30 });
setUser({ ...user, age: 31 }); // ๊ธฐ์กด ๊ฐ์ฒด ์†์„ฑ์„ ์œ ์ง€ํ•˜๋ฉด์„œ age๋งŒ ๋ณ€๊ฒฝ

๐Ÿ“Œ ์ˆ˜์—… ์งˆ๋ฌธ ์ •๋ฆฌ

1. ์ปดํฌ๋„ŒํŠธ ์ž‘์„ฑ ์‹œ ํ•จ์ˆ˜ ์„ ์–ธ์‹๋ณด๋‹ค ํ•จ์ˆ˜ ํ‘œํ˜„์‹์„ ์„ ํ˜ธํ•˜๋Š” ์ฃผ๋œ ์ด์œ ๊ฐ€ ํ˜ธ์ด์ŠคํŒ… ๋ฐฉ์ง€์ธ์ง€ ๊ถ๊ธˆ

โœ… ๊ฐ•์‚ฌ๋‹˜ ๋‹ต๋ณ€

ํ•จ์ˆ˜ ํ‘œํ˜„์‹์„ ์„ ํ˜ธํ•˜๋Š” ์ด์œ ๋Š”

  1. ์ฝ”๋“œ ์ผ๊ด€์„ฑ: ๋‹ค๋ฅธ ๋ณ€์ˆ˜/์ƒ์ˆ˜์ฒ˜๋Ÿผ const๋กœ ์„ ์–ธํ•ด ์ฝ”๋“œ ์Šคํƒ€์ผ์„ ํ†ต์ผํ•  ์ˆ˜ ์žˆ์Œ
  2. ํ™”์‚ดํ‘œ ํ•จ์ˆ˜์˜ ์žฅ์ : ๊ฐ„๊ฒฐํ•œ ๋ฌธ๋ฒ• + this๊ฐ€ ์ƒ์œ„ ์Šค์ฝ”ํ”„๋ฅผ ๋”ฐ๋ฆ„
  3. ๋ชจ๋˜ JS ํŒจํ„ด: ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ๊ณผ ์–ด์šธ๋ฆผ
  4. ํ˜ธ์ด์ŠคํŒ… ๋ฐฉ์ง€: ์„ ์–ธ ์ „์— ์‚ฌ์šฉํ•˜์ง€ ๋ชปํ•˜๋„๋ก ๋ง‰์•„ ์ฝ”๋“œ ํ๋ฆ„์„ ๋” ๋ช…ํ™•ํ•˜๊ฒŒ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ์Œ
1
2
3
4
5
// ํ•จ์ˆ˜ ์„ ์–ธ์‹ - ํ˜ธ์ด์ŠคํŒ…๋จ
function MyComponent() { /*...*/ }

// ํ•จ์ˆ˜ ํ‘œํ˜„์‹ - ํ˜ธ์ด์ŠคํŒ…๋˜์ง€ ์•Š์Œ
const MyComponent = () => { /*...*/ };

2. React ๋ฆฌ์ŠคํŠธ ๋ Œ๋”๋ง ์‹œ ํ•ญ๋ชฉ ์ถ”๊ฐ€/์‚ญ์ œ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ key={index}๋ฅผ ์“ฐ๋ฉด ์•ˆ ๋˜๋Š”์ง€? ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์€?

โœ… ๊ฐ•์‚ฌ๋‹˜ ๋‹ต๋ณ€

React์—์„œ key={index}๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ํ•ญ๋ชฉ์ด ์ถ”๊ฐ€๋˜๊ฑฐ๋‚˜ ์‚ญ์ œ๋  ๋•Œ ๋ฌธ์ œ๋ฅผ ์ผ์œผํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.

  1. ๋น„ํšจ์œจ์ ์ธ ๋ฆฌ๋ Œ๋”๋ง - React๋Š” ํ‚ค๋ฅผ ํ†ตํ•ด ์–ด๋–ค ์š”์†Œ๊ฐ€ ๋ณ€๊ฒฝ๋˜์—ˆ๋Š”์ง€ ํŒŒ์•…ํ•˜๋Š”๋ฐ, ์ธ๋ฑ์Šค๊ฐ€ ๋ฐ”๋€Œ๋ฉด ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์€ ์ปดํฌ๋„ŒํŠธ๊นŒ์ง€ ๋ถˆํ•„์š”ํ•˜๊ฒŒ ๋ฆฌ๋ Œ๋”๋ง๋ฉ๋‹ˆ๋‹ค.
  2. ์ƒํƒœ ๊ด€๋ฆฌ ์ด์Šˆ - ์ธ๋ฑ์Šค๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด ์ปดํฌ๋„ŒํŠธ ์ƒํƒœ๊ฐ€ ์„ž์ด๊ฑฐ๋‚˜ ํ˜ผ๋ž€์„ ์ผ์œผํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  3. ์„ฑ๋Šฅ ์ €ํ•˜ - ๋ถˆํ•„์š”ํ•œ DOM ์กฐ์ž‘์ด ๋ฐœ์ƒํ•ด ์„ฑ๋Šฅ์ด ์ €ํ•˜๋ฉ๋‹ˆ๋‹ค.

๋” ๋‚˜์€ ๋ฐฉ๋ฒ•

  1. ๊ณ ์œ ํ•œ ID ์‚ฌ์šฉ
1
2
3
4
5
6
7
8
9
10
11
12
const todoList = [
  { id: 'task-1', text: '์šด๋™ํ•˜๊ธฐ' },
  { id: 'task-2', text: '์‡ผํ•‘ํ•˜๊ธฐ' }
];

return (
  <ul>
    {todoList.map(item => (
      <li key={item.id}>{item.text}</li>
    ))}
  </ul>
);
  1. ๋ฐ์ดํ„ฐ๊ฐ€ ์—†๋‹ค๋ฉด ID ์ƒ์„ฑํ•˜๊ธฐ
1
2
import { v4 as uuidv4 } from 'uuid';
const newItem = { id: uuidv4(), text: '์ƒˆ ํ•ญ๋ชฉ' };
  1. ํ•ญ๋ชฉ ์ž์ฒด์˜ ๊ณ ์œ ํ•œ ๊ฐ’ ํ™œ์šฉ
1
<li key={user.email}>{user.name}</li>

์ธ๋ฑ์Šค๋ฅผ key๋กœ ์จ๋„ ๊ดœ์ฐฎ์€ ๊ฒฝ์šฐ

  • ๋ฆฌ์ŠคํŠธ๊ฐ€ ์ •์ ์ด๋ฉฐ ์ ˆ๋Œ€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์„ ๋•Œ
  • ํ•ญ๋ชฉ์˜ ์ˆœ์„œ๊ฐ€ ๋ฐ”๋€Œ์ง€ ์•Š์„ ๋•Œ
  • ํ•ญ๋ชฉ์— ๊ณ ์œ  ID๊ฐ€ ์—†์„ ๋•Œ

END

This post is licensed under CC BY 4.0 by the author.