๐ธ 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 ์ฑ ์คํ
- localhost:5173์์ ์ฑ ํ์ธ ๊ฐ๋ฅ
- vite.config.js์์ ํฌํธ ๋ณ๊ฒฝ ๊ฐ๋ฅ
Vite๋ฅผ ์ฌ์ฉํ๋ ์ด์
- ๋น ๋ฅธ ๊ฐ๋ฐ ์๋ฒ
- Vite๋ ๋ฒ๋ค๋ง ์์ด ๋ค์ดํฐ๋ธ ES ๋ชจ๋์ ํ์ฉํ์ฌ ๋งค์ฐ ๋น ๋ฅธ ๊ฐ๋ฐ ์๋ฒ๋ฅผ ์ ๊ณตํฉ๋๋ค. ๊ธฐ์กด์ webpack ๊ธฐ๋ฐ ๋๊ตฌ(create-react-app)๋ณด๋ค ํจ์ฌ ๋น ๋ฅด๊ฒ ์์๋ฉ๋๋ค.
- ๋น ๋ฅธ ํซ ๋ชจ๋ ๊ต์ฒด(HMR)
- ์ฝ๋๋ฅผ ๋ณ๊ฒฝํ ๋ ํ์ด์ง๊ฐ ๊ฑฐ์ ์ฆ์ ์
๋ฐ์ดํธ๋์ด ๊ฐ๋ฐ ๊ฒฝํ์ด ํฌ๊ฒ ํฅ์๋ฉ๋๋ค.
- ์ต์ ํ๋ ๋น๋ : ํ๋ก๋์
๋น๋ ์ Rollup์ ์ฌ์ฉํ์ฌ ์ต์ ํ๋ ๊ฒฐ๊ณผ๋ฌผ์ ์์ฑํฉ๋๋ค.
- ๊ฐ์ํ๋ ์ค์
- ๊ธฐ๋ณธ ์ค์ ์ด ์ ๋์ด ์์ด ์ถ๊ฐ ๊ตฌ์ฑ ์์ด๋ ๋ฐ๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค.
- TypeScript ๋ฐ JSX ๊ธฐ๋ณธ ์ง์
- ๋ณ๋์ ์ค์ ์์ด TypeScript์ JSX๋ฅผ ์ฆ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
- ๋ค์ํ ํ๋ ์์ํฌ ํ
ํ๋ฆฟ
- React ์ธ์๋ Vue, Preact, Lit ๋ฑ ๋ค์ํ ํ๋ ์์ํฌ ํ
ํ๋ฆฟ์ ์ง์ํฉ๋๋ค.
- ๊ฐ๋ฒผ์ด ์์กด์ฑ : create-react-app์ ๋นํด ์์กด์ฑ์ด ์ ์ด ์ค์น ํฌ๊ธฐ๊ฐ ์์ต๋๋ค.
- ์ต์ ์น ํ์ค ํ์ฉ : ES ๋ชจ๋์ ๊ธฐ๋ฐ์ผ๋ก ํ์ฌ ์ต์ ์น ํ์ค์ ์ ๊ทน ํ์ฉํฉ๋๋ค.
๐ Vite Scaffolding ๊ตฌ์กฐ
ํด๋/ํ์ผ | ์ค๋ช
|
---|
node_modules | ์์กด์ฑ ๋ชจ์ |
public | ์ ์ ํ์ผ ํด๋ |
src | ๊ฐ๋ฐ ์์ค ์ฝ๋ ํด๋ |
โ assets | ์ด๋ฏธ์ง, ํฐํธ ๋ฑ ์ ์ ์์ฐ |
index.html | ์ง์
HTML ํ์ผ |
main.jsx | React ์ฑ ์ง์
์ |
App.jsx / App.css | ์ฃผ์ ์ปดํฌ๋ํธ ๋ฐ ์คํ์ผ |
index.css | ์ ์ญ ์คํ์ผ |
package.json | ํ๋ก์ ํธ ์ค์ ๋ฐ ์คํฌ๋ฆฝํธ |
eslint.config.js | ์ต์ ํ๋ซ ESLint ๊ตฌ์ฑ |
vite.config.js | Vite ๋น๋ ์ค์ |
.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)
๊ฐ์ฒด ํ์
(Object Types)
- ์์ ํ์
์ ์ ์ธํ ๋ชจ๋ ์๋ฃํ์ด ๊ฐ์ฒด ํ์
- ๊ฐ์ฒด ํ์
์ ์์ ํ์
๊ณผ ๋ฌ๋ฆฌ ๋ณต์กํ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ฅผ ํํํ ์ ์๋ค.
- ๊ฐ์ฒด๋ ํ๋กํผํฐ(์์ฑ)์ ์งํฉ์ผ๋ก, ๊ฐ ํ๋กํผํฐ๋ ํค์ ๊ฐ์ผ๋ก ๊ตฌ์ฑ๋๋ค.
- ์๋ฐ์คํฌ๋ฆฝํธ์์๋ ํจ์๋ ๊ฐ์ฒด์ ํ ํํ๋ก ๊ฐ์ฃผํ๋ค.
- Object: ํค(Key)์ ๊ฐ(Value)์ ๊ฐ์ง ํ๋กํผํฐ์ ์ปฌ๋ ์
์ด๋ค.
- Array: ์์๊ฐ ์๋ ๊ฐ์ ์งํฉ์ด๋ค.
- Function: ์คํ ๊ฐ๋ฅํ ์ฝ๋ ๋ธ๋ก์ด๋ค.
- Date, RegExp ๋ฑ์ ๋ด์ฅ ๊ฐ์ฒด๋ค๋ ์๋ค.
์์ ํ์
๊ณผ ๊ฐ์ฒด ํ์
์ ์ฐจ์ด
ํญ๋ชฉ | ์์ ํ์
(Primitive) | ๊ฐ์ฒด ํ์
(Object) |
---|
์ ์ฅ ๋ฐฉ์ | ๊ฐ ์์ฒด๊ฐ ๋ณ์์ ์ง์ ์ ์ฅ๋จ | ๋ฉ๋ชจ๋ฆฌ์ ๊ฐ์ฒด๊ฐ ์ ์ฅ๋๊ณ ๋ณ์๋ ๊ทธ ์ฐธ์กฐ(์ฃผ์)๋ฅผ ์ ์ฅ |
๋ถ๋ณ์ฑ | ๋ถ๋ณ(Immutable) โ ๊ฐ์ ๋ณ๊ฒฝํ๋ฉด ์ ๊ฐ์ด ํ ๋น๋จ | ๊ฐ๋ณ(Mutable) โ ๊ฐ์ฒด์ ์์ฑ์ ๋ณ๊ฒฝ ๊ฐ๋ฅ |
๋น๊ต ๋ฐฉ์ | ๊ฐ ๋น๊ต (=== ๋ ๊ฐ์ด ๊ฐ์ผ๋ฉด true) | ์ฐธ์กฐ ๋น๊ต (=== ๋ ๋์ผ ๊ฐ์ฒด์ผ ๋๋ง true) |
๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ | ๊ณ ์ ๋ ํฌ๊ธฐ, ๊ด๋ฆฌ๊ฐ ๋จ์ | ํฌ๊ธฐ๊ฐ ๊ฐ๋ณ์ , ๋์ ์ผ๋ก ๊ด๋ฆฌ |
๋ณต์ฌ ๋ฐฉ์ | ๊ฐ ๋ณต์ฌ (๊น์ ๋ณต์ฌ) | ์ฐธ์กฐ ๋ณต์ฌ (์์ ๋ณต์ฌ) |
์ ์ฅ ์์น | Stack | Heap |
์ฑ๋ฅ ์ธก๋ฉด | ๋ ๋น ๋ฆ (๊ฐ๋ณ๊ณ ์คํ์ ์ ์ฅ๋จ) | ๋ ๋๋ฆผ (ํ ์ ๊ทผ + ์ฐธ์กฐ ๊ตฌ์กฐ ๋๋ฌธ) |
๐ก ๊ฐ์ฒด, ๋ฐฐ์ด, ํจ์ ๋ฑ์ ์ ๋ถ ์ฐธ์กฐ ํ์
์ด๋ฉฐ, ๋ณ์๋ ์ค์ ๊ฐ์ด ์๋ 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๋ ์ ๊ตฌ๋ณํด์ ์ฌ์ฉํ๋๊ฐ?
ํ์ผ ํ์ฅ์ ๊ตฌ๋ถ์ ์ฃผ์ ์ด์
- ๋ช
ํํ ์๋ ์ ๋ฌ
.jsx
: React ์ปดํฌ๋ํธ, UI ๊ด๋ จ ์์ ํฌํจ.js
: ์ผ๋ฐ JavaScript ๋ก์ง, ์ ํธ ํจ์ ๋ฑ ๋ด๋น
- ๋๊ตฌ ๋ฐ ํธ์ง๊ธฐ ์ต์ ํ
- ํธ์ง๊ธฐ(VS Code ๋ฑ)๊ฐ ํ์ผ ์ ํ์ ๋ง๋ ๋ฌธ๋ฒ ๊ฐ์กฐ์ ์๋ ์์ฑ ๊ธฐ๋ฅ์ ์ ๊ณต
- JSX ์ค๋ํซ๊ณผ React ์๋์์ฑ ์ง์
- ๋น๋ ์์คํ
์ต์ ํ
- ์นํฉ์ด๋ Babel ๊ฐ์ ๋น๋ ๋๊ตฌ๊ฐ ํ์ผ ์ ํ์ ๋ฐ๋ผ ๋ค๋ฅธ ์ฒ๋ฆฌ
- JSX ํ์ผ๋ง React ๋ณํ ๊ณผ์ ์ ๊ฑฐ์น๋๋ก ์ค์ ํ ์ ์์ด ๋น๋ ์ฑ๋ฅ ํฅ์
- ์ฝ๋๋ฒ ์ด์ค ๊ตฌ์ฑ์ ๋ช
ํ์ฑ
- ํ์ ๊ฐ ํ์ผ์ ์ญํ ์ ์ฝ๊ฒ ์ดํด
- ๋๊ท๋ชจ ํ๋ก์ ํธ์์ ํ์ผ์ ๋ชฉ์ ์ ์ฝ๊ฒ ํ์
- ๊ด์ฌ์ฌ์ ๋ถ๋ฆฌ (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>
);
}
|
useState(0)
์ ์ด๊ธฐ๊ฐ์ด 0์ธ ์ํ๋ฅผ ์์ฑcount
๋ ํ์ฌ ์ํ๊ฐ์ ์ ์ฅsetCount
๋ count
์ํ๋ฅผ ์
๋ฐ์ดํธํ๋ ํจ์์
๋๋ค.
์ฃผ์ ํน์ง
- ์ํ ๋ณ๊ฒฝ ์ ์๋ ๋ฆฌ๋ ๋๋ง
- ์ด์ ์ํ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์
๋ฐ์ดํธ ์ ํจ์ํ ์ฌ์ฉ:
setCount(prev => prev + 1)
- ๊ฐ์ฒด ์ํ ๊ด๋ฆฌ ์ ์ ์ฒด ๊ฐ์ฒด๋ฅผ ๋ณต์ฌํ์ฌ ์
๋ฐ์ดํธ
1
2
| const [user, setUser] = useState({ name: 'ํ๊ธธ๋', age: 30 });
setUser({ ...user, age: 31 }); // ๊ธฐ์กด ๊ฐ์ฒด ์์ฑ์ ์ ์งํ๋ฉด์ age๋ง ๋ณ๊ฒฝ
|
๐ ์์
์ง๋ฌธ ์ ๋ฆฌ
1. ์ปดํฌ๋ํธ ์์ฑ ์ ํจ์ ์ ์ธ์๋ณด๋ค ํจ์ ํํ์์ ์ ํธํ๋ ์ฃผ๋ ์ด์ ๊ฐ ํธ์ด์คํ
๋ฐฉ์ง์ธ์ง ๊ถ๊ธ
โ
๊ฐ์ฌ๋ ๋ต๋ณ
ํจ์ ํํ์์ ์ ํธํ๋ ์ด์ ๋
- ์ฝ๋ ์ผ๊ด์ฑ: ๋ค๋ฅธ ๋ณ์/์์์ฒ๋ผ
const
๋ก ์ ์ธํด ์ฝ๋ ์คํ์ผ์ ํต์ผํ ์ ์์ - ํ์ดํ ํจ์์ ์ฅ์ : ๊ฐ๊ฒฐํ ๋ฌธ๋ฒ +
this
๊ฐ ์์ ์ค์ฝํ๋ฅผ ๋ฐ๋ฆ - ๋ชจ๋ JS ํจํด: ํจ์ํ ํ๋ก๊ทธ๋๋ฐ๊ณผ ์ด์ธ๋ฆผ
- ํธ์ด์คํ
๋ฐฉ์ง: ์ ์ธ ์ ์ ์ฌ์ฉํ์ง ๋ชปํ๋๋ก ๋ง์ ์ฝ๋ ํ๋ฆ์ ๋ ๋ช
ํํ๊ฒ ์ ์งํ ์ ์์
1
2
3
4
5
| // ํจ์ ์ ์ธ์ - ํธ์ด์คํ
๋จ
function MyComponent() { /*...*/ }
// ํจ์ ํํ์ - ํธ์ด์คํ
๋์ง ์์
const MyComponent = () => { /*...*/ };
|
2. React ๋ฆฌ์คํธ ๋ ๋๋ง ์ ํญ๋ชฉ ์ถ๊ฐ/์ญ์ ๊ฐ ์๋ ๊ฒฝ์ฐ key={index}
๋ฅผ ์ฐ๋ฉด ์ ๋๋์ง? ๋ค๋ฅธ ๋ฐฉ๋ฒ์?
โ
๊ฐ์ฌ๋ ๋ต๋ณ
React์์ key={index}๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ํญ๋ชฉ์ด ์ถ๊ฐ๋๊ฑฐ๋ ์ญ์ ๋ ๋ ๋ฌธ์ ๋ฅผ ์ผ์ผํฌ ์ ์๋ค.
- ๋นํจ์จ์ ์ธ ๋ฆฌ๋ ๋๋ง - React๋ ํค๋ฅผ ํตํด ์ด๋ค ์์๊ฐ ๋ณ๊ฒฝ๋์๋์ง ํ์
ํ๋๋ฐ, ์ธ๋ฑ์ค๊ฐ ๋ฐ๋๋ฉด ๋ณ๊ฒฝ๋์ง ์์ ์ปดํฌ๋ํธ๊น์ง ๋ถํ์ํ๊ฒ ๋ฆฌ๋ ๋๋ง๋ฉ๋๋ค.
- ์ํ ๊ด๋ฆฌ ์ด์ - ์ธ๋ฑ์ค๊ฐ ๋ณ๊ฒฝ๋๋ฉด ์ปดํฌ๋ํธ ์ํ๊ฐ ์์ด๊ฑฐ๋ ํผ๋์ ์ผ์ผํฌ ์ ์์ต๋๋ค.
- ์ฑ๋ฅ ์ ํ - ๋ถํ์ํ DOM ์กฐ์์ด ๋ฐ์ํด ์ฑ๋ฅ์ด ์ ํ๋ฉ๋๋ค.
๋ ๋์ ๋ฐฉ๋ฒ
- ๊ณ ์ ํ 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>
);
|
- ๋ฐ์ดํฐ๊ฐ ์๋ค๋ฉด ID ์์ฑํ๊ธฐ
1
2
| import { v4 as uuidv4 } from 'uuid';
const newItem = { id: uuidv4(), text: '์ ํญ๋ชฉ' };
|
- ํญ๋ชฉ ์์ฒด์ ๊ณ ์ ํ ๊ฐ ํ์ฉ
1
| <li key={user.email}>{user.name}</li>
|
์ธ๋ฑ์ค๋ฅผ key๋ก ์จ๋ ๊ด์ฐฎ์ ๊ฒฝ์ฐ
- ๋ฆฌ์คํธ๊ฐ ์ ์ ์ด๋ฉฐ ์ ๋ ๋ณ๊ฒฝ๋์ง ์์ ๋
- ํญ๋ชฉ์ ์์๊ฐ ๋ฐ๋์ง ์์ ๋
- ํญ๋ชฉ์ ๊ณ ์ ID๊ฐ ์์ ๋
END