1.JSX
JSX(JavaScript XML)๋ Javascript์ XML์ ์ถ๊ฐํ ํ์ฅํ ๋ฌธ๋ฒ์ด๋ค.
JSX ์์ด React ๋ง๋ค๊ธฐ
main.ts
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
function main() {
const container = document.getElementById('root');
if (!container) {
return;
}
const root = ReactDOM.createRoot(container);
root.render(React.createElement(App, null));
}
main();
App.ts
import React, { useState } from 'react';
import Greeting from './components/Greeting';
type ImageProps = {
src: string;
alt?: string;
width?: number;
}
function Image({ src, alt = '', width }: ImageProps) {
return (
React.createElement('img', { src, alt, width: width ?? 'auto' })
);
}
export default function App() {
const [count, setCount] = useState(0);
const handleClick = (value: number) => {
setCount(count + value);
};
return (
React.createElement(
'div',
null,
React.createElement(Greeting, { name: 'wholeman!' }),
React.createElement(Image,
{
src: '/images/test.jpg',
alt: 'Test Image',
width: 200
}),
React.createElement('p', null, 'Count: ', count),
[1, 2, 3, 4, 5].map((i) => React.createElement('button',
{ type: 'button', key: i, onClick: () => handleClick(i) },
'+',
i)),
)
);
}
components/Greeting.ts
import React from 'react';
export default function Greeting({ name }: {
name: string;
}) {
return (
React.createElement('p', null, 'Hello, ', name)
);
}
React์์ JSX๋ฅผ ์ฌ์ฉํ๋ ๋ชฉ์
๊ทผ๋ณธ์ ์ผ๋ก, JSX
๋ React.createElement(component, props, ...children)
ํจ์์ ๋ํ ๋ฌธ๋ฒ์ ์คํ์ ์ ๊ณตํ ๋ฟ์ด๋ค.
const element = (
<h1 className="greeting">
Hello, world!
</h1>
);
const element = React.createElement(
'h1',
{className: 'greeting'},
'Hello, world!'
);
๋ ์์๋ ๋์ผํ ๊ฒฐ๊ณผ๊ฐ์ ๋ํ๋ด์ค๋ค.
ํ์ง๋ง React.createElement
๋ก ์์ฑํ์์ ๋ ๋ณด๋ค JSX
๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ํจ์ฌ ์ง๊ด์ ์ด๊ณ ๊ฐ๋
์ฑ์ด ์ข๊ณ JSX
๋ ํ๋์ ํ์ผ์ ์๋ฐ์คํฌ๋ฆฝํธ์ HTML์ ๋์์ ์์ฑ ํ ์ ์๋ ์ ์ด ์ฅ์ ์ด๋ค.
Syntactic sugar
์ง๊ด์ ์ด์ง๋ ์์ง๋ง ์ฝ๋์ ์์ ์ค์ผ ์ ์๋ ๋ฌธ๋ฒ์ ์ธ ์คํ์ ์๋ฏธํ๋ค.
๋ํ์ ์ธ Syntactic sugar
1. Ternary Operator(์ผํญ ์ฐ์ฐ์)
์ผํญ ์ฐ์ฐ์ ์ฌ์ฉ ์
setProviderList(prev => prev.map(item => (
if (item.id === search.provider) {
return { ...item, isChecked: !item.isChecked }
} else {
return item
}
)));
์ผํญ ์ฐ์ฐ์ ์ฌ์ฉ ํ
setProviderList(prev => prev.map(item => (
item.id === search.provider ? { ...item, isChecked: !item.isChecked } : item
)));
์ผํญ ์ฐ์ฐ์๋ฅผ ์ฌ์ฉํ๊ฒ ๋๋ฉด ์ฌ์ฉ ์ ๋ณด๋ค ํจ์ฌ ๊ฐ๊ฒฐํ๊ฒ ์์ฑ์ด ๊ฐ๋ฅํ๋ค.
2. Object Spread / Array Spread (๊ฐ์ฒด ์ ๊ฐ / ๋ฐฐ์ด ์ ๊ฐ)
setProviderList(prev => prev.map(item => (
item.id === search.provider ? { ...item, isChecked: !item.isChecked } : item
)));
์์ map ์์์ ๊ฐ์ฒด์ ์ผ๋ถ๋ถ์ ๋ณ๊ฒฝํ๊ณ ์ถ์ ๋ { ...item, isChecked: !item.isChecked }
์ ๊ฐ์ด ๊ธฐ์กด์ ๊ฐ์ฒด์์ ๊ฐ์ ์ ๊ฐํ๊ณ ๋ณ๊ฒฝํ๊ณ ์ ํ๋ ๊ฐ์ ๋ณ๊ฒฝํ๋ค.
const DEFAULT_CONFIG = {
preserveWhitespace: true,
noBreaks: false,
foo: "bar",
};
const USER_CONFIG = {
noBreaks: true,
}
const config = { ...DEFAULT_CONFIG, ...USER_CONFIG };
์์ ๊ฐ์ด ๋ ๊ฐ์ฒด๋ฅผ ๋ชจ๋ ์ ๊ฐํด์ ํ๋์ ๊ฐ์ฒด๋ก ๋ณ๊ฒฝํ๋ ๊ฒ๋ ๊ฐ๋ฅํ๋ค. ์ด๋ ๊ฐ์ key ๊ฐ์ value๊ฐ
๋ค๋ฅผ ๊ฒฝ์ฐ ๋ค์ ๋ค์ด์ค๋ ๊ฐ์ฒด์ ๊ฐ์ผ๋ก ๋ณํ๋๋ค.
๋ฐฐ์ด๋ ๊ฐ์ฒด์ ์์ ์ ๋์ผํ๊ฒ ์ ๊ฐ ํ ํ๋์ ๋ฐฐ์ด๋ก ๋ณํฉํ๋๊ฒ ๊ฐ๋ฅํ๋ค. ๋ค๋ง ๋ฐฐ์ด์ ๊ฒฝ์ฐ๋ key๊ฐ ์๊ธฐ
๋๋ฌธ์ ๊ฐ๊ฐ ๋ค๋ฅธ ๋ฐฐ์ด์ ์ ๊ฐํด์ ๋ณํฉ ํ ๋ ์ค๋ณต๋๋ ๊ฐ๋ ๋ชจ๋ ๋ค์ด๊ฐ๊ฒ ๋๋ค.
const arr1 = ['a', 'b', 'c'];
const arr2 = ['c', 'd', 'e'];
const arr3 = [...arr1, ...arr2];
// console.log(arr3) => ['a', 'b', 'c', 'c', 'd', 'e']
3. Object Destructuring / Array Destructuring (๊ฐ์ฒด ๊ตฌ์กฐ ๋ถํด ํ ๋น / ๋ฐฐ์ด ๊ตฌ์กฐ ๋ถํด ํ ๋น)
export default function LectureBody({ classroomLecture }: Props): ReactElement {
const {
moduleList, classroomId, lastSectionId, lastSectionType,
} = classroomLecture;
...
}
์ปดํฌ๋ํธ props๋ก ์ ๋ฌ๋ฐ์ ๊ฐ์ฒด๋ฅผ ๊ตฌ์กฐ ๋ถํดํ์ฌ ํ์ํ ๊ฐ๋ง ์ฌ์ฉํ ์ ์๋ค.
// ์ด๋ฆ๊ณผ ์ฑ์ ์์๋ก ๊ฐ์ง ๋ฐฐ์ด
let arr = ["Bora", "Lee"]
// ๊ตฌ์กฐ ๋ถํด ํ ๋น์ ์ด์ฉํด
// firstName์ arr[0]์
// surname์ arr[1]์ ํ ๋นํ์๋ค.
let [firstName, surname] = arr;
๋ฐฐ์ด๋ ๋ง์ฐฌ๊ฐ์ง๋ก ๊ตฌ์กฐ ๋ถํดํ์ฌ ๋ณ์๋ก ํ ๋นํ์ฌ ์ฌ์ฉ ํ ์ ์๋ค.
// ๋ ๋ฒ์งธ ์์๋ ํ์ํ์ง ์์
let [firstName, , title] = ["Julius", "Caesar", "Consul", "of the Roman Republic"];
alert( title ); // Consul
์ถ๊ฐ๋ก ํ์ํ์ง ์์ ๋ฐฐ์ด์ ๊ฐ์ ์ผํ๋ฅผ ์ฌ์ฉํ์ฌ ์์๋ฅผ ๋ฒ๋ฆด ์ ์๋ค.
4. Object Rest / Array Rest (๊ฐ์ฒด ๋๋จธ์ง ์ฐ์ฐ์, ๋ฐฐ์ด ๋๋จธ์ง ์ฐ์ฐ์)
const {
moduleList, classroomId, lastSectionId, lastSectionType, ...rest,
} = classroomLecture;
let [name1, name2, ...rest] = ['a', 'b', 'c', 'c', 'd', 'e'];
console.log(rest); // ['c', 'c', 'd', 'e'];
rest๋ ๋๋จธ์ง ๋ฐฐ์ด ์์๋ค์ด ์ ์ฅ๋ ์๋ก์ด ๋ฐฐ์ด์ด ๋๋ค.
rest ๋์ ์ ๋ค๋ฅธ ์ด๋ฆ์ ์ฌ์ฉํด๋ ๋๋๋ฐ, ๋ณ์ ์์ ์ ์ธ ๊ฐ(...)์ ๋ณ์๊ฐ ๊ฐ์ฅ ๋ง์ง๋ง์ ์์นํด์ผ ํ๋ค.
function sum(...theArgs) {
let total = 0;
for (const arg of theArgs) {
total += arg;
}
return total;
}
console.log(sum(1, 2, 3));
// Expected output: 6
console.log(sum(1, 2, 3, 4));
// Expected output: 10
ํจ์์ ๋งค๊ฐ๋ณ์๋ฅผ ์ ๋ฌ ํ ๋๋ ์ฌ์ฉ์ด ๊ฐ๋ฅํ๋ค.
5. Nullish coalescing (null ๋ณํฉ ์ฐ์ฐ์)
๊ธฐ์กด ๋ฌธ๋ฒ
const name = user.name || 'Guest';
null ๋ณํฉ ์ฐ์ฐ์ ๋ฌธ๋ฒ
const name = user.name ?? 'Guest';
๊ธฐ์กด ๋ฌธ๋ฒ์ ๊ฒฝ์ฐ ์กด์ฌํ์ง ์๊ฑฐ๋ null, undefined, 0 ๋๋ ๋น ๋ฌธ์์ด๊ณผ ๊ฐ์ ์๋ชป๋ ๊ฐ์ด ์๋ ๊ฒฝ์ฐ ๊ธฐ๋ณธ๊ฐ 'Guest'๊ฐ name ๋ณ์์ ํ ๋น๋๋ค.
๊ทธ๋ฌ๋ ์ด๋ฌํ ๊ธฐ์กด ๋ฌธ๋ฒ์ ์ ๊ทผ ๋ฐฉ์์ name ์์ฑ์ด ์กด์ฌํ์ง๋ง ์๋ชป๋ ๊ฐ์ ๊ฐ์ง๊ณ ์์ด๋ ๊ธฐ๋ณธ๊ฐ์ ํ ๋นํ๋ค๋ ๋จ์ ์ด ์๋ค.
null ๋ณํฉ ์ฐ์ฐ์(??)๋ ํน๋ณํ null ๋๋ undefined ๊ฐ๋ง ํ์ธํ๋ ๊ธฐ์กด ๊ตฌ๋ฌธ์ ๋์์ด๋ค. ๊ฐ์ด null ๋๋ undefined์ธ ๊ฒฝ์ฐ์๋ง ๊ธฐ๋ณธ๊ฐ์ ํ ๋นํ๊ณ ๊ฐ์ด falsy์ธ ๊ฒฝ์ฐ์๋ ํ ๋นํ์ง ์๋๋ค.
5. Arrow function (ํ์ดํ ํจ์)
function add(a, b) {
return a + b;
}
const add = (a, b) => a + b;
ํ์ดํ ํจ์๋ function ํค์๋๋ฅผ ์ฌ์ฉํ๋ ๋์ ํ์ดํ(=>)๋ฅผ ์ฌ์ฉํ์ฌ ํจ์๋ฅผ ๊ฐ๊ฒฐํ๊ฒ ์ ์ํ ์ ์๋ค.
6. Template literals(ํ
ํ๋ฆฟ ๋ฆฌํฐ๋ด)
const name = 'John';
console.log('Hello, ' + name + '!');
const name = 'John';
console.log(`Hello, ${name}!`);
ํ ํ๋ฆฟ ๋ฆฌํฐ๋ด์ ์ฌ์ฉํ๋ฉด ์์๋ฐ์ดํ๋ ํฐ๋ฐ์ดํ ๋์ ๋ฐฑํฑ(`)์ ์ฌ์ฉํ์ฌ ๋ฌธ์์ด์ ์ ์ํ ์ ์๋ค. ์ด๋ ๊ฒ ํ๋ฉด ๋ฌธ์์ด ์์ ๋ณ์์ ํํ์์ ๋ ์ฝ๊ฒ ํฌํจํ ์ ์๋ค.
7. Optional chaining(์ ํ์ ์ฐ๊ฒฐ)
// ๊ธฐ์กด ๋ฌธ๋ฒ
const person = { name: 'John', address: { city: 'New York' } };
const city = person.address && person.address.city;
// Optional chaining ๋ฌธ๋ฒ
const person = { name: 'John', address: { city: 'New York' } };
const city = person.address?.city;
Optional chaining
์ ์ฌ์ฉํ๋ฉด ๊ฐ์ฒด์ ์กด์ฌ ์ฌ๋ถ์ ๋ํ ๊ฑฑ์ ์์ด ๊ฐ์ฒด์ ์์ฑ์ ์ก์ธ์คํ ์ ์๋ค. ์์ฑ์ด ์ ์๋์ง ์์ ๊ฒฝ์ฐ ์ค๋ฅ๋ฅผ ๋ฐ์์ํค๋ ๋์ ๊ฒฐ๊ณผ๊ฐ ์ ์๋์ง ์๋ค
์์ ๋ด์ฉ ๋ง๊ณ ๋ฐฐ์ด ๋งค์๋
๋ ๋ํ์ ์ธ ๋ฌธ๋ฒ์ ์ธ ์คํ์ ํฌํจ๋๋ค.
const arr = [1, 2, 3, 4, 5];
const doubled = arr.map(x => x * 2);
const evens = arr.filter(x => x % 2 === 0);
const sum = arr.reduce((acc, x) => acc + x, 0);
React.createElement
React.createElement
๋ React
์์ ๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ ์ปดํฌ๋ํธ ์์ฑ ๋ฐฉ๋ฒ ์ค ํ๋์ด๋ค. ์ด ํจ์๋ฅผ ์ฌ์ฉํ์ฌ React ์์๋ฅผ ์์ฑํ๊ณ ์ด๋ฅผ ๋ ๋๋งํ ์ ์๋ค.
React.createElement
ํจ์๋ ์ธ ๊ฐ์ ์ธ์๊ฐ ํ์ํ๋ค.
์์์ ์ ํ (๋ฌธ์์ด ๋๋ ์ปดํฌ๋ํธ ํจ์)
์์์ ์์ฑ (๋๋ "props") ๋๋ null
์์ ์์๋ค
React.createElement('div', { className: 'test' }, 'Hello, World!')
์ ์ฝ๋๋ ์๋์ ๊ฐ์ React ์์๋ฅผ ๋ง๋ค์ด๋ธ๋ค.
<div className="test">Hello, World!</div>
React.createElement
ํจ์๋ ์ปดํฌ๋ํธ ํจ์๋ฅผ ์ฒซ ๋ฒ์งธ ์ธ์๋ก ์ฌ์ฉํ ์๋ ์๋ค. ์ด ๊ฒฝ์ฐ ํจ์ ์ด๋ฆ์ ๋ฌธ์์ด๋ก ์ ๋ฌํ๊ฑฐ๋ ES6์ ํ์ดํ ํจ์ ๊ตฌ๋ฌธ์ ์ฌ์ฉํ์ฌ ์ง์ ํจ์๋ฅผ ์ ๋ฌํ ์ ์๋ค. ๋ํ ์์ฑ ๋ฐ ์์ ์์๋ค์ ์ปดํฌ๋ํธ ํจ์์ ์ธ์๋ก ์ ๋ฌ๋๋ค.
function MyComponent(props) {
return React.createElement('div', { className: 'test' }, props.message);
}
React.createElement(MyComponent, { message: 'Hello, World!' });
<div className="test">Hello, World!</div>
React Element
interface ReactElement<P = any, T extends string | JSXElementConstructor<any> = string | JSXElementConstructor<any>> {
type: T;
props: P;
key: Key | null;
}
React Element
์ ์์ฑ(property)
type: ์์์ ์ ํ, ์๋ฅผ ๋ค์ด "div" ๋๋ ์ฌ์ฉ์ ์ง์ ์ปดํฌ๋ํธ ํจ์์ด๋ค.
props: ์์์ ์์ฑ, ์๋ฅผ ๋ค์ด className, style, onClick ๋ฑ์ ์์ฑ์ด ํฌํจ๋๋ค.
key: ์ปดํฌ๋ํธ๊ฐ ์ ๋ฐ์ดํธ๋ ๋ React๊ฐ ์์๋ฅผ ์๋ณํ๋ ๋ฐ ์ฌ์ฉ๋๋ ๊ณ ์ ํ ์๋ณ์์ด๋ค.
ref: React ์์์ ๋ํ ์ฐธ์กฐ(reference)๋ฅผ ๋ง๋๋ ๋ฐ ์ฌ์ฉ๋๋ค.
React Element
๋ React
์์ ๋ ๋๋ง๋๋ ๊ฐ์ฅ ์์ ๋จ์์ด๊ณ , JavaScript
๊ฐ์ฒด๋ก, React
์์๋ฅผ ๋ํ๋ธ๋ค. React
์์๋ ํ๋ฉด์ ๋ ๋๋ง๋๋ ์์๋ฅผ ๋ํ๋ด๋ฉฐ, ๋ค๋ฅธ React
์์๋ค๊ณผ ๊ฒฐํฉํ์ฌ React
์ปดํฌ๋ํธ๋ฅผ ๋ง๋๋ ๋ฐ ์ฌ์ฉ๋๋ค.
React Element
๋ ๋ถ๋ณ๊ฐ์ฒด(immutable object)์ด๋ฉฐ, ํ ๋ฒ ์์ฑ๋๋ฉด ์์ ๋ ์ ์๋ค. ์ด๋ฌํ ๋ถ๋ณ์ฑ์ React
์ ์ฑ๋ฅ์ ํฅ์์ํค๋ ๋ฐ ๊ธฐ์ฌํ๋๋ฐ React
๋ ๋ณํ๊ฐ ํ์ํ ๊ฒฝ์ฐ ์๋ก์ด React Element
๋ฅผ ๋ง๋ค๊ณ ๊ธฐ์กด์ Element
์ ์ Element
๋ฅผ ๋น๊ตํ์ฌ ์ต์ํ์ ๋ณ๊ฒฝ๋ง ์ ์ฉํ๋ฏ๋ก ๋ ๋๋ง ์ฑ๋ฅ์ ํฅ์์ํจ๋ค.
React StrictMode
์ ํ๋ฆฌ์ผ์ด์ ์์ ์ ์ฌ์ ์ธ ๋ฌธ์ ๋ฅผ ๋ฏธ๋ฆฌ ๊ฐ์งํ๊ณ ํด๊ฒฐํ ์ ์๋๋ก ๋์์ฃผ๋ ๋๊ตฌ StrictMode๋ ๊ฐ๋ฐ ๋ชจ๋์์๋ง ๋์ํ๋ฉฐ, ๋ธ๋ผ์ฐ์ ์์๋ ์๋ฌด๋ฐ ์ํฅ์ ๋ฏธ์น์ง ์๋๋ค.
StrictMode๋ฅผ ํตํด์ ์ป์ ์ ์๋ ํจ๊ณผ
๋ถ์ํจ๊ณผ ๊ฒ์ฌ
: React ์ปดํฌ๋ํธ์์ ๋ถ์ํจ๊ณผ(์ผ๋ฐ์ ์ผ๋ก ์๋ช ์ฃผ๊ธฐ ๋ฉ์๋, useEffect ๋ฑ)๋ฅผ ์ฌ์ฉํ ๋ ๊ฒฝ๊ณ ๋ฉ์์ง๋ฅผ ์ถ๋ ฅํ์ฌ ์ ์ฌ์ ์ธ ๋ฌธ์ ๋ฅผ ๊ฐ์งํ ์ ์๋ค.๋ ๊ฑฐ์ ๋ฌธ์์ด ref ๊ฒฝ๊ณ
: ๋ฌธ์์ด์ ์ฌ์ฉํ์ฌ ref๋ฅผ ์์ฑํ๋ฉด ๊ฒฝ๊ณ ๋ฉ์์ง๊ฐ ํ์๋๋ค. ๋ฌธ์์ด ref๋ ๋ ์ด์ ๊ถ์ฅ๋์ง ์์ผ๋ฉฐ, ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ref๋ฅผ ์์ฑํ๋ ๊ฒ์ด ์ข๋ค.๋ ๊ฑฐ์ ์๋ช ์ฃผ๊ธฐ ๋ฉ์๋ ๊ฒฝ๊ณ
: ๋ ๊ฑฐ์ ์๋ช ์ฃผ๊ธฐ ๋ฉ์๋(componentWillMount, componentWillReceiveProps, componentWillUpdate)๋ฅผ ์ฌ์ฉํ๋ฉด ๊ฒฝ๊ณ ๋ฉ์์ง๊ฐ ํ์๋๋ค. ์ด๋ฌํ ๋ฉ์๋๋ ๋ ์ด์ ๊ถ์ฅ๋์ง ์์ผ๋ฉฐ, ๋์ ์ componentDidMount, componentDidUpdate, getDerivedStateFromProps ๋ฐ getSnapshotBeforeUpdate ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข๋ค.์์ ํ์ง ์์ ์๋ช ์ฃผ๊ธฐ ๋ฉ์๋ ๊ฒฝ๊ณ
: ์์ ํ์ง ์์ ์๋ช ์ฃผ๊ธฐ ๋ฉ์๋(UNSAFE_componentWillMount, UNSAFE_componentWillReceiveProps, UNSAFE_componentWillUpdate)๋ฅผ ์ฌ์ฉํ๋ฉด ๊ฒฝ๊ณ ๋ฉ์์ง๊ฐ ํ์๋๋ค. ์ด๋ฌํ ๋ฉ์๋๋ ํฅํReact
์ ๋ฐ์ดํธ์์ ์ญ์ ๋ ์์ ์ด๋ฉฐ, ๋์ ์ getDerivedStateFromProps ๋ฐ getSnapshotBeforeUpdate ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข๋ค.
StrictMode๋ฅผ ์ฌ์ฉํ๋ฉด ์ ํ๋ฆฌ์ผ์ด์
์์ ๋ฐ์ํ ์ ์๋ ์ ์ฌ์ ์ธ ๋ฌธ์ ๋ฅผ ์กฐ๊ธฐ์ ๊ฐ์งํ ์ ์์ผ๋ฏ๋ก, React
์ ํ๋ฆฌ์ผ์ด์
์ ๊ฐ๋ฐ ๋ฐ ์ ์ง๋ณด์๋ฅผ ๋ณด๋ค ์์ ํ๊ฒ ์ํํ ์ ์๋ค.
VDOM(Virtual DOM)์ด๋?
Virtual DOM
(๊ฐ์ DOM)์ React
์ ํต์ฌ ๊ฐ๋
์ค ํ๋์ด๋ค. Virtual DOM
์ ๋ธ๋ผ์ฐ์ ๊ฐ ์ง์ ์กฐ์ํ๋ ์ค์ DOM
๊ณผ๋ ๋ณ๋๋ก, JavaScript ๊ฐ์ฒด๋ก ์ด๋ฃจ์ด์ง ๊ฐ์ฒด ๋ชจ๋ธ์ด๋ค.
React
์์ ์ปดํฌ๋ํธ๊ฐ ์
๋ฐ์ดํธ๋ ๋, ์ค์ DOM
์ ์กฐ์ํ๋ ๊ฒ์ด ์๋๋ผ, Virtual DOM
์ ์
๋ฐ์ดํธํ๊ณ , ์ด์ ๊ณผ ์๋ก์ด Virtual DOM
์ ๋น๊ตํ์ฌ ๋ณ๊ฒฝ๋ ๋ถ๋ถ๋ง ์ค์ DOM
์ ์ ์ฉํ๋ค. ์ด๋ฅผ ํตํด DOM
์กฐ์ ํ์๋ฅผ ์ต์ํํ๊ณ , ๋น ๋ฅธ ๋ ๋๋ง์ ๊ตฌํํ ์ ์๋ค.
React
์์๋ ์ด๋ฌํ Virtual DOM
์ ๊ตฌํํ๊ณ , ๊ฐ ์ปดํฌ๋ํธ์ ์ํ์ ์์ฑ์ด ๋ณ๊ฒฝ๋ ๋๋ง๋ค Virtual DOM
์ ์
๋ฐ์ดํธํ๊ณ , ๋ณ๊ฒฝ๋ ๋ถ๋ถ๋ง ์ต์ ํ๋ ๋ฐฉ์์ผ๋ก ์ค์ DOM
์ ์ ์ฉํ์ฌ UI๋ฅผ ์
๋ฐ์ดํธํ๋ค.
DOM์ด๋?
DOM
(Document Object Model)์ ๋ธ๋ผ์ฐ์ ์์ ์น ํ์ด์ง์ HTML ๋ฌธ์๋ฅผ ๋ก๋ํ๊ณ ํ์ฑํ ๊ฒฐ๊ณผ๋ฌผ์ ๋ํ๋ด๋ ๊ฐ์ฒด ๋ชจ๋ธ์ด๋ค. ์ฆ, HTML, XML ๋๋ XHTML ๋ฌธ์๋ฅผ ๋ธ๋ผ์ฐ์ ๊ฐ ์ดํดํ ์ ์๋ ๊ฐ์ฒด ๋ชจ๋ธ๋ก ๋ณํํ์ฌ(HTML ๋ฌธ์๋ฅผ ์ด๋ฃจ๋ ๋ชจ๋ ์์๋ค์ ๊ฐ์ฒด๋ก ํํ๋๋ฉฐ, ์ด๋ฌํ ๊ฐ์ฒด๋ค์ ์๋ก ๊ณ์ธต์ ์ธ ๊ด๊ณ๋ฅผ ๊ฐ์ง๊ณ ์๋ค.), ์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ์ฌ์ฉํ์ฌ ๋ฌธ์์ ๊ตฌ์กฐ, ์คํ์ผ, ์ฝํ
์ธ ๋ฑ์ ๋์ ์ผ๋ก ์กฐ์ํ ์ ์๊ฒ ํ๋ค.
DOM๊ณผ Virtual DOM์ ์ฐจ์ด
DOM
์ ๋ธ๋ผ์ฐ์ ์์ ์ง์ ์กฐ์๋๋ ์ค์ ๊ฐ์ฒด์ด๋ฏ๋ก, DOM
์กฐ์ ์์
์ ๋ธ๋ผ์ฐ์ ์ ์ฑ๋ฅ์ ํฌ๊ฒ ์ ํ์ํฌ ์ ์๋ค.
๋ฐ๋ฉด, Virtual DOM
์ React
์์ ๋ด๋ถ์ ์ผ๋ก ๊ด๋ฆฌ๋๋ ๊ฒ์ผ๋ก, ๋ธ๋ผ์ฐ์ ๊ฐ ์ง์ ์กฐ์ํ์ง ์์ผ๋ฏ๋ก DOM ์กฐ์ ์์
์ ๋น์ฉ์ ํฌ๊ฒ ์ ๊ฐํ ์ ์๋ค.
Reconciliation(์ฌ์กฐ์ ) ๊ณผ์ ์ ๋ฌด์์ธ๊ฐ?
React
์์ Reconciliation(์ฌ์กฐ์ )
์ Virtual DOM
์์ ์ด๋ฃจ์ด์ง๋ ๊ณผ์ ์ผ๋ก, ์ด์ ์ํ์ ํ์ฌ ์ํ์ Virtual DOM
์ ๋น๊ตํ์ฌ ๋ณ๊ฒฝ๋ ๋ถ๋ถ๋ง ์ค์ DOM
์ ์
๋ฐ์ดํธํ๋ ๊ณผ์ ์ด๋ค.
Reconciliation
์ Virtual DOM
์ ๋
ธ๋๋ฅผ ์ํํ๋ฉฐ ์ด์ ์ํ์ ๋น๊ตํ์ฌ ๋ณ๊ฒฝ๋ ๋ถ๋ถ์ ์ฐพ๋๋ค. ์ด ๊ณผ์ ์์ React
๋ ํจ์จ์ ์ผ๋ก ๋น๊ต๋ฅผ ์ํํ๊ธฐ ์ํด ๋ค์ํ ์ต์ ํ ๊ธฐ์ ์ ์ฌ์ฉํ๋ค. ์๋ฅผ ๋ค์ด, ๊ฐ์ ์ปดํฌ๋ํธ๊ฐ ์ฌ๋ฌ ๋ฒ ๋ ๋๋ง๋ ๋, React
๋ ์ด์ ๋ ๋๋ง ๊ฒฐ๊ณผ์ ํ์ฌ ๋ ๋๋ง ๊ฒฐ๊ณผ๋ฅผ ๋น๊ตํ์ฌ ๋ณ๊ฒฝ๋ ๋ถ๋ถ๋ง ์
๋ฐ์ดํธํ๋ค.
Reconciliation
์ ์ด์ ์ ์ฑ๋ฅ๊ณผ ์ฌ์ฉ์ ๊ฒฝํ ๊ฐ์ ์ด๋ค. React
๋ Virtual DOM
์ ์ฌ์ฉํ์ฌ ๋ณ๊ฒฝ๋ ๋ถ๋ถ๋ง ๋ ๋๋งํ๋ฏ๋ก, ํ์ํ ์ต์ํ์ DOM
์กฐ์๋ง ์ํ๋์ด ์ฑ๋ฅ์ด ํฅ์๋๊ณ , ๋ณ๊ฒฝ๋ ๋ถ๋ถ๋ง ์
๋ฐ์ดํธ๋๋ฏ๋ก, ๋ถํ์ํ ํ๋ฉด ๊น๋นก์์ ๋ฐฉ์งํ๊ณ ์ฌ์ฉ์ ๊ฒฝํ์ ๊ฐ์ ํ ์ ์๋ค.
Aha Moment
์ ๊ฐ ๊ตฌ๋ฌธ์ ๋ํด์ MDN์ ํ์ธํ์ ๋ ์๋์ ๊ฐ์ ๋ด์ฉ์ ์ถ๊ฐ๋ก ํ์ธ ํ ์ ์์๋ค.
apply()
๋์ฒด
์ผ๋ฐ์ ์ผ๋ก ๋ฐฐ์ด์ ์๋ฆฌ๋จผํธ๋ฅผ ํจ์์ ์ธ์๋ก ์ฌ์ฉํ๊ณ ์ ํ ๋ Function.prototype.apply()
๋ฅผ ์ฌ์ฉํ์๋ค.
function myFunction(x, y, z) { }
let args = [0, 1, 2];
myFunction.apply(null, args);
์ ๊ฐ ๊ตฌ๋ฌธ์ ์ฌ์ฉํด ์ ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ์ด ์์ฑ๋ ์ ์๋ค.
function myFunction(x, y, z) { }
let args = [0, 1, 2];
myFunction(...args);
๋ฐฐ์ด ๋ณต์ฌ
let arr = [1, 2, 3];
let arr2 = [...arr]; // arr.slice() ์ ์ ์ฌ
arr2.push(4);
// arr2 ์ [1, 2, 3, 4] ์ด ๋จ
// arr ์ ์ํฅ์ ๋ฐ์ง ์๊ณ ๋จ์ ์์
๋ฐฐ์ด ๋ณํฉ
let arr1 = [0, 1, 2];
let arr2 = [3, 4, 5];
// arr2 ์ ๋ชจ๋ ํญ๋ชฉ์ arr1 ์ ๋ถ์
arr1 = arr1.concat(arr2);
์ ๊ฐ ๊ตฌ๋ฌธ์ ์ฌ์ฉํ์ฌ ์์ ๋์ผํ๊ฒ ๋ณ๊ฒฝ ํ ์ ์๋ค.
let arr1 = [0, 1, 2];
let arr2 = [3, 4, 5];
arr1 = [...arr1, ...arr2]; // arr1 ์ ์ด์ [0, 1, 2, 3, 4, 5]
๋ฐฐ์ด ๋ณํฉ ๋ฐ ์์๋ณ๊ฒฝ
let arr1 = [0, 1, 2];
let arr2 = [3, 4, 5];
// arr2 ์ ๋ชจ๋ ํญ๋ชฉ์ arr1 ์ ์์ ๋ถ์
Array.prototype.unshift.apply(arr1, arr2) // arr1 ์ ์ด์ [3, 4, 5, 0, 1, 2] ๊ฐ ๋จ
์ ๊ฐ ๊ตฌ๋ฌธ์ ์ฌ์ฉํ์ฌ ์์ ๋์ผํ๊ฒ ๋ณ๊ฒฝ ํ ์ ์๋ค.
let arr1 = [0, 1, 2];
let arr2 = [3, 4, 5];
arr1 = [...arr2, ...arr1]; // arr1 ์ ์ด์ [3, 4, 5, 0, 1, 2] ๊ฐ ๋จ
์ ๊ฐ ๊ตฌ๋ฌธ์ด ์ถ๊ฐ๋๊ณ ๋์ ๋ฐ์ดํฐ์ ๋ถ๋ณ์ฑ์ ์ ์งํ๊ธฐ ๋ ์ฉ์ดํด์ง ๊ฒ ๊ฐ๋ค๊ณ ์๊ฐ์ด ๋ค์๋ค. ์ถ๊ฐ๋ก ์ ๊ฐ ๊ตฌ๋ฌธ์ด ์ด๋์์ ํ์๋์ด์ ธ ์๋์ง ์ ์ ์๋ ์๊ฐ์ด์๋ค.
์ด๋ฒ์ ๋ฐ๋ธ๋
ธํธ ํค์๋๋ฅผ ๊ฒ์ํด๋ณด๋ฉด์ ๋๋ ๋ถ๋ถ์ React
๊ฐ ์ด๋ค ๋ฌธ์ ์ ์ ํด๊ฒฐํ๊ธฐ ์ํด์ JSX
๋ฅผ ๋์
ํ๊ณ VDOM
์ ๋์
ํ๊ฒ ๋์๋์ง ์๊ฐํด๋ณด๋ ๊ณ๊ธฐ๊ฐ ๋์๋ ๊ฒ ๊ฐ๋ค. ํ์ฌ ์ค๋ฌด์์ ์์
ํ๋ฉด์๋ ์ด ๊ธฐ์ ์ด ์ ๋์ค๊ฒ ๋์๋์ง์ ๋ํด์ ๊น๊ฒ ๊ณ ๋ฏผ ํด๋ณธ์ ์ด ์๊ณ ๋๋ต์ ์ธ ๋ถ๋ถ์ ๋ํด์๋ง ์๊ณ ์์๋ค๋ฉด ์ด๋ฒ์ React
์ ๋ํ ์ ๋ฐ์ ์ธ ๋ด์ฉ์ ์ฐพ์๋ณด๊ณ ์ ๋ฆฌํ๋ฉด์ React
์ ์ ๋ณด๋ค ๋ ๊ฐ๊น์์ง ๋๋์ด ๋ค์๋ค. ์ด๋ฒ์ ์ ๋ฆฌํ ๋
ธํธ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ง์์ ์ผ๋ก ๋จธ๋ฆฟ์์ ์ง์ด ๋ฃ๋ ๊ณผ์ ์ ํตํด์ ๊ธฐ๋ณธ์ ์ ๊ธฐ์ตํ๋๋ก ํด์ผ๊ฒ ๋ค.
Reference
Last updated