๋ฐ๋๋ผ JS๋ก SSR๊ณผ CSR์ ๊ตฌํํด๋ณด๋ฉด์ innerHTML์ ์ฐ์ง ์๊ธฐ ์ํด react์์ Element๋ฅผ ์ถ๊ฐํ๋ ๋ฐฉ์์ ๋ํด ํ์ตํ๋ ๊ณผ์ ์ ์์ฑํ๋ ค ํฉ๋๋ค.
์ ๋ฒ ํฌ์คํ ์์์ ์ ์ฌํ๊ฒ, ๋ฐ๋๋ผ js๋ก์ ์น ํ์ด์ง ๊ตฌํ์ ์ฒ์์ด๋ผ ๋ง์ด ๋ฏ์ค๊ธฐ๋ ํ๊ณ , ์ด๋ ต๊ธฐ๋ ํ ๊ฒ ๊ฐ์ต๋๋ค.
์ ๋ฒ ํฌ์คํ ์์ ์์ฑํ๋ ๊ฒ์ฒ๋ผ, CSR๊ณผ SSR์ ๋ํด ๊น์ด ๊ณ ๋ฏผํ๊ณ ํ์ตํด๋ณด์๊ณ , ๋ฐ๋๋ผ JS๋ก CSR๊ณผ SSR์ ๊ตฌํํด๋ณด๋ ๊ณผ์ ์ ๊ฑฐ์ณค์ต๋๋ค.
๊ทธ๋ฐ๋ฐ CSR๋ก ๊ตฌํํ ๋ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ ํ๋ฉด์ ๊ทธ๋ ค์ฃผ๋ ๊ณผ์ ์์ ์ด์ฉ ์ ์์ด innerHTML
๋ก ๋์ ์ ๊ทผํด ์๋ฆฌ๋จผํธ๋ฅผ ์ถ๊ฐํด์ผ ํ์ต๋๋ค.
ํ์ง๋ง ํญ์ react๋ฅผ ์ฌ์ฉํ๋ ์ฌ๋์ผ๋ก์, โinnerHTML
์ ์ฐ์ง ๋ง์์ผ ํ๋คโ๋ ์๊ฐ์ด ์ง๋ฐฐ์ ์ด๋ผ ์ฐ๋ฉด์๋ ์ฐ์ฐํจ์ ๊ฐ์ถ ์ ์์์ต๋๋ค.
innerHTML
์ ์ฌ์ฉํ CSR, ๊ทธ๋ฆฌ๊ณ ๋ณด์ ๋ฌธ์ โinnerHTML
์ ์ฐ์ง ๋ง์์ผ ํ๋คโ๋ ์๊ฐ ๋๋ฌธ์ ๊ณ ๋ฏผ์ด ๋ง์์ต๋๋ค. ์ฃผ์
๋ ๊ฐ์ด ์
์ฑ ์คํฌ๋ฆฝํธ๋ฅผ ํฌํจํ ๊ฒฝ์ฐ ์ด๋ฅผ ๊ทธ๋๋ก ์คํํ๊ฒ ๋๋ ๋ณด์ ๋ฌธ์ ๊ฐ ์๊ธฐ ๋๋ฌธ์ innerHTML
์ฌ์ฉ์ ์ง์ํด์ผ ํ๋๋ฐ, ์๊ฐํด๋ณด๋ React๋ก ํ๋ก์ ํธ๋ฅผ ํ ๋๋ innerHTML
์ ์ ํ ์ฌ์ฉํ ์ ์ด ์๋ค๋ ์ฌ์ค์ ๊นจ๋ฌ์์ต๋๋ค.
๊ทธ๋ผ React์์๋ ์ด๋ป๊ฒ ๋์ ์ ๊ทผํด ์๋ฆฌ๋จผํธ๋ฅผ ์ถ๊ฐํ๋์ง ๊ถ๊ธํด์ก์ต๋๋ค.
React ๋ด๋ถ์์๋ innerHTML์ ์ฌ์ฉํ๋ ๊ฑธ๊น? ๋ง์ฝ ์ฌ์ฉํ์ง ์๋๋ค๋ฉด ์ด๋ป๊ฒ ์๋ฆฌ๋จผํธ๋ฅผ ์ถ๊ฐํ๋ ๊ฒ์ผ๊น?
์ด ๊ถ๊ธ์ฆ์ ํด๊ฒฐํ๊ธฐ ์ํด React์ ๋์ ๋ฐฉ์์ ์กฐ๊ธ ๋ ๊น์ด ์ดํด๋ณด๊ธฐ๋ก ํ์ต๋๋ค.
innerHTML
์ ์ธ๊น?๋ง์ฝ React๊ฐ ๋ด๋ถ์ ์ผ๋ก innerHTML
์ ์ฌ์ฉํ๊ณ ์๋ค๋ฉด, ์ ๋ ๋ฐ๋๋ผ JS์์ innerHTML
์ ์จ๋ ๋์ง ์์๊น ํ๋ ์๊ฐ์ด ๋ค์๊ณ , ๋ง์ฝ React๊ฐ ๋ค๋ฅธ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ๋ค๋ฉด, ๊ทธ ๋ฐฉ์์ด ๋ฌด์์ธ์ง ์์๋ด์ผ๊ฒ ๋ค๋ ์๊ฐ์ ํ์์ต๋๋ค.
์ฐ์ ๊ฒฐ๋ก ๋ถํฐ ๋งํ์๋ฉด React ๋ด๋ถ์ ๋ํ ๊ณต๋ถ๋ฅผ ํด๋ณด๋, React๋ innerHTML
์ ์ฌ์ฉํ์ง ์์ต๋๋ค. ๊ทธ๋ ๋ค๋ฉด React๋ ์ด๋ป๊ฒ ์๋ฆฌ๋จผํธ๋ฅผ ์ถ๊ฐํ๋ ๊ฒ์ธ์ง ๊ถ๊ธํด์ก๊ณ , ํ์ธํ๊ธฐ ์ํด์ ์ฝ๋๊ฐ ์ด๋ป๊ฒ ๋์ํ๋์ง๋ถํฐ ์ดํด๋ณด์์ต๋๋ค .
createElement()
์ฐ์ React์์๋ JSX๋ผ๋ ๋ ํนํ(?) ๋ฌธ๋ฒ์ ์ฌ์ฉํฉ๋๋ค.
๊ฐ๋จํ๊ฒ๋ง ์ธ๊ธํ์๋ฉด JSX๋ HTML๊ณผ ๋งค์ฐ ๋น์ทํ ๋ฌธ๋ฒ์ด๊ณ , React ์ปดํฌ๋ํธ๋ฅผ ์ง๊ด์ ์ผ๋ก ์์ฑํ ์ ์๊ฒ ๋์์ค๋๋ค.
ํ์ง๋ง JSX๋ ๋ธ๋ผ์ฐ์ ์์ ๋ฐ๋ก ์ดํด๋์ง ์์ผ๋ฏ๋ก, Babel์ด๋ผ๋ ๋๊ตฌ๊ฐ ์ด ์ฝ๋๋ฅผ transformํ์ฌ ์๋ฐ์คํฌ๋ฆฝํธ ์ฝ๋๋ก ๋ณํํด์ค๋๋ค. (JSX ๊ด๋ จ ํ์ต์ ๋ฐ๋ก ์ ๋ฆฌํด๋ ์์ ์ ๋๋ค.)
์๋ฅผ ๋ค์ด ๋ค์๊ณผ ๊ฐ์ JSX ์ฝ๋๋ฅผ ์์ฑํ๋ค๊ณ ๊ฐ์ ํด๋ณด๊ฒ ์ต๋๋ค.
<div id="app">
<h1>Hello, World!</h1>
<button onClick={() => alert('Clicked!')}>Click me</button>
</div>
์ ์ฝ๋์ ๋ํด์ Babel์ ์๋์ ๊ฐ์ ํํ๋ก ๋ณํํด์ค๋๋ค.
const element = createElement(
'div',
{ id: 'app' },
createElement('h1', null, 'Hello, World!'),
createElement(
'button',
{ onClick: () => alert('Clicked!') },
'Click me'
)
);
์ ์ฝ๋์์ React.createElement()
ํจ์๋ฅผ ํ์ธํ ์ ์์ต๋๋ค. ์ด ํจ์๋ JSX ์ฝ๋๋ฅผ ์๋ฐ์คํฌ๋ฆฝํธ ์ฝ๋๋ก ๋ณํํ๋ ์ญํ ์ ํฉ๋๋ค.
react๋ฅผ ์ฌ์ฉํ๋ ๊ฐ๋ฐ์๋ค์ ๋ณดํต jsx ํํ๋ก ์ฝ๋๋ฅผ ์์ฑํ๊ธฐ ๋๋ฌธ์, createElement ํจ์๋ฅผ ์ฌ์ฉํ ์ผ์ด ๊ฑฐ์ ์์ด ์ด๋ฒ ๊ธฐํ์ ์ฒ์ ํ์ตํ๊ฒ ๋์์ต๋๋ค.
createElement
์ ๋ด๋ถ์์ React Element ์์ฑReact์ createElement
ํจ์๋ JSX๋ก ์์ฑ๋ ์ฝ๋๋ฅผ ๋ฐํ์ผ๋ก Element๋ฅผ ์์ฑํฉ๋๋ค. createElement
์ ์ฝ๋๋ฅผ ๋ณด๋ฉด, ๋ค์๊ณผ ๊ฐ์ด props
์ children
(์์ ์์)์ ์ค์ ํ ํ, ์ด๋ฅผ ๋ฐํ์ผ๋ก ReactElement
๋ผ๋ ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ ๊ณผ์ ์ ๋ณผ ์ ์์ต๋๋ค.
export function createElement(type, config, children) {
let propName;
props[propName] = config[propName];
key = '' + config.key;
props.children = children;
return ReactElement(
type,
key,
ref,
self,
source,
ReactCurrentOwner.current,
props,
);
}
์ด createElement
ํจ์์์ ํน์ดํ(?) ์ ์ ReactElement
๋ผ๋ ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ค๋ ๊ฒ์
๋๋ค.
์ผ๋ฐ์ ์ธ DOM ์๋ฆฌ๋จผํธ๋ฅผ ๋ฐํํ๋ ๊ฒ์ด ์๋๋ผ, React๋ง์ ๋ ํนํ ์๋ฆฌ๋จผํธ ๊ตฌ์กฐ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ๋๋ค.
function ReactElement(type, key, ref, self, source, owner, props) {
const element = {
$$typeof: REACT_ELEMENT_TYPE,
type: type,
key: key,
ref: ref,
props: props,
_owner: owner,
};
return element;
}
์ฌ๊ธฐ์ ReactElement
๋ ์ค์ DOM ์๋ฆฌ๋จผํธ๊ฐ ์๋, React์์ ์ฌ์ฉํ๋ ๊ฐ์ DOM์ ํด๋นํฉ๋๋ค.
(๋ฌผ๋ก ๊ณต์ ๋ฌธ์์์๋ ๊ฐ์ DOM์ด๋ผ๊ณ ์ฝ ์ง์ด ์ธ๊ธํ์ง๋ ์์ต๋๋ค.)
createElement
ํจ์๋ฅผ ํตํด ReactElement
๋ฅผ ์์ฑํ๋ค๋ ๊ฒ๊น์ง๋ ์๊ฒ ๋๋ฐ ๊ทธ๋ ๋ค๋ฉด ์ค์ DOM์๋ ์ธ์ ์
ํ๋ ๊ฒ์ธ์ง ๋ ๊ถ๊ธํด์ก์ต๋๋ค.
์ง๊ธ๊น์ง์ ๊ณผ์ ์ ๊ฑฐ์น๋ฉด ์์ฑ๋ง ํ๊ณ html์ ์ ํ๋ ๊ณผ์ ์ ์๋ค๊ณ ๋๊ปด์ก๊ธฐ ๋๋ฌธ์ ๋๋ค.
๊ฒฐ๋ก ์ ์ผ๋ก๋ ์ด ReactElement
๊ฐ์ฒด๋ React์ ๋ ๋๋ง ๊ณผ์ ์์ ์ฒ๋ฆฌ๋์ด ๋ง์ง๋ง์ ์ค์ DOM์ ๋ฐ์๋๋ ๊ฒ์ธ๋ฐ, ์ด ๋ฌธ์ฅ์ ์ดํดํ๊ธฐ ์ํด react-dom
์ ๊ณต๋ถํด๋ณด์์ผ ํ์ต๋๋ค.
์์์ ๋ง๋ค์ด์ง ReactElement ๊ฐ์ ๊ฒ๋ค์ html
๊ณผ ์ฐ๊ฒฐํด์ฃผ์ด์ผ ํ๋ ๊ฒ์ธ๋ฐ, ์ด๋ ์ฌ์ฉ๋๋ ๊ฒ์ด ๋ฐ๋ก react-dom
์ธ ๊ฒ์
๋๋ค.
๋จผ์ react๋ฅผ ํตํด ๊ฐ๋ฐํ๋ฉด, ์ฌ์ฉ์์๊ฒ ๋ณด์ฌ์ง๋ ๊ฒฐ๋ก ์ ์ธ ํ๋ฉด์ index.html
ํ์ผ์
๋๋ค.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<title>App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>
์ด html ํ์ผ์์ ์ ์ผํ๊ฒ div ํ๊ทธ๊ฐ ํ๋ ์๊ธฐ ๋๋ฌธ์, (์ฌ์ง์ด ์์๋ ์๋ฌด ์ปจํ ์ธ ๋ ์กด์ฌํ์ง ์์ต๋๋ค)
<div id="root"></div>
์ด div ๊ตฌ์กฐ ๋ด์ ์์์ ๋ง๋ค์ด๋์๋ ReactElement
๊ฐ ๋ค์ด๊ฐ๊ฒ ๋๋ ๊ฒ์
๋๋ค.
react๋ฅผ ์ฌ์ฉํด๋ดค๋ค๋ฉด ๋ชจ๋๊ฐ ์๋ค์ํผ, ์๋์ ๊ฐ์ index.js ํ์ผ์ด ์กด์ฌํฉ๋๋ค.
// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './app';
ReactDOM.render(
<App />,
document.getElementById('root')
);
์ด index.js ํ์ผ์์ document.getElementById('root')
์ฝ๋๋ ์ index.html
ํ์ผ์ ์ ์ผํ div ํํฌ๋ฅผ ๊ฐ๋ฆฌํค๋ ๊ฒ์ด๊ณ , root
๋ผ๋ id๋ฅผ ์ด์ฉํด์ react-dom
์ผ๋ก js ์ฝ๋์ ์ฐ๊ฒฐํด์ฃผ๋ ๊ฒ์
๋๋ค.
์์ธํ ๊ณผ์ ์ ์ ์ด๋ณด์๋ฉด,
import ReactDOM from 'react-dom';
react-dom
์ด๋ผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ย React
๋ผ๋ ํด๋์ค๋ฅผ import ํด์ค๊ณ ,
ReactDOM.render(
<App />,
document.getElementById('root')
)
๊ฐ์ ธ์จ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ย ReactDOM
์ด๋ผ๋ ํด๋์ค์ ์๋ย render
ย ํจ์๋ฅผ ์ด์ฉํด์
์ฆ,ย index.html
์ ์๋ย <div id="root"></div>
์ ์ผํ div ํ๊ทธ์ <App />
์ด๋ผ๋ ์ปดํฌ๋ํธ(js ํ์ผ)๋ฅผ ์ฐ๊ฒฐํ๋ ๊ฒ์
๋๋ค.
์์ ์์ฑํ๋ ์ ์ฒด ํ๋ฆ์ ๊ฐ๋จํ๊ฒ ์์ฑํด๋ณด์๋ฉด,
๐ก ๊ฐํธํ๊ฒ jsx๋ก ๊ตฌํํ ์ฝ๋๋ฅผ
babel
์ดcreateElement()
ํจ์๋ก ๋ณํํด์ฃผ๊ณ , ์ดcreateElement()
ํจ์๋ฅผ ๊ฑฐ์น๋ฉดReactElement
๋ผ๋ ํ์ ์ผ๋ก ๋ฐํํด์ค๋๋ค. ์ด๋ ๊ฒ ๋ฐํ๋ Element๋ค์react-dom
์ ํตํดindex.html
์ ์๋ ํ๊ทธ์ ์ ๊ทผํ์ฌ<App />
๊ณผ ๊ฐ์ ์ปดํฌ๋ํธ์ ์ฐ๊ฒฐํด์ฃผ์ด html ์ฝ๋์ธ ๊ฒ์ฒ๋ผ CSR ๋ฐฉ์์ผ๋ก ํ๋ฉด์ ๋ ๋๋ง ํด์ค๋๋ค.
์ฝ๋๋ก ์ ๋ฆฌํด๋ณด์๋ฉด ์๋์ ๊ฐ์ต๋๋ค.
App.jsx
ํ์ผ์ด ์๋์ ๊ฐ๋ค๋ฉด,
// App.jsx
import React from 'react';
import from './app.css';
function App() {
return (
<div id="app">
<h1>Hello, World!</h1>
<button onClick={() => alert('Clicked!')}>Click me</button>
</div>
)
}
export default App;
babel์ ํตํด
const element = createElement(
'div',
{ id: 'app' },
createElement('h1', null, 'Hello, World!'),
createElement(
'button',
{ onClick: () => alert('Clicked!') },
'Click me'
)
);
์ด๋ ๊ฒ ๋ณํ๋๊ณ ,
react-dom
์ ํตํด ์์ index.js
์์
<div id="root"></div>
div ํ๊ทธ์ <App />
์ปดํฌ๋ํธ๋ฅผ ์ฐ๊ฒฐํด์ฃผ์ด
ํ๋ฉด์ ๋ ๋๋ง๋๋ ๊ฒ์ ๋๋ค.
๊ฒฐ๋ก ์ ์ผ๋ก React๋ innerHTML
์ ์ฌ์ฉํ์ง ์๊ณ , ์์ฒ๋ผ ReactElement
๋ผ๋ ๊ฐ์ฒด๋ฅผ ๋ฐํํด ๊ฐ์ DOM์์ ๊ด๋ฆฌํ๊ธฐ ๋๋ฌธ์ ์ ๊ฐ ๊ฑฑ์ ํ๋ ๋ณด์ ๋ฌธ์ ๋ ์์ฐ์ค๋ฝ๊ฒ ํด๊ฒฐ๋ฉ๋๋ค.
์ฐ์ ์ด๋ ๊ฒ ๊น์ด ๊ณต๋ถํด๋ณด๋ฉด์ React์ ์๋ฆฌ๋จผํธ ์์ฑ ๋ฐฉ์์ ์ ๊ฐ ๋ฐ๋๋ผ JS์์ ์ฌ์ฉํ innerHTML
๊ณผ๋ ๋งค์ฐ ๋ค๋ฅด๋ค๋ ๊ฒ์ ์๊ฒ ๋์์ต๋๋ค.
ํนํ, react๋ฅผ ์์ฃผ ์ฐ๋ฉด์๋ react-dom
๊ณผ react
์ ๊ด๊ณ๋, ์ด๋ค ๋ฐฉ์์ผ๋ก ๋ ๋๋ง ๋๋์ง ์ ํ ๋ชฐ๋์๋๋ฐ, ์ด๋ฐ ๊ธฐ๋ณธ์ ์ธ ๊ฒ๋ ๊ถ๊ธํดํ์ง ์์๋ ์ ๊ฐ ๋ถ๋๋ฝ๊ณ ์ด์ ์ผ ์๊ฒ ๋์๋ค๋ ๊ฒ์ด ์ฐฝํผํ์ต๋๋คโฆ.
๊ทธ๋๋ ์ด๋ฒ ๊ณต๋ถ๋ฅผ ํตํด์ react๊ฐ ์ด๋ค ๋ฐฉ์์ผ๋ก ๋ ๋๋ง๋๋์ง ๋จ์ํ โ๊ฐ์ DOM ์ฌ์ฉโ, โSPA ๋ฐฉ์โ ๋ฑ ๊ฒ์ ๊ฐ๋ ๋ง ์๋ ๊ฒ์ด ์๋, ๊ตฌ์ฒด์ ์ธ ํ๋ฆ์ ์ ์ ์์ด ๋๋ฌด ์ข์์ต๋๋ค.
์ด๋ฐ ์๋ฆฌ๋ฅผ ๋ฐํ์ผ๋ก ์ ๋ ๋ฐ๋๋ผ JS๋ก ๋จ์ํ innerHTML
์ ์์กดํ์ง ์๊ณ , React์ ๊ตฌ์กฐ๋ฅผ ์ฐธ๊ณ ํด ์ ๋ง์ ์๋ฆฌ๋จผํธ ์์ฑ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๊ตฌํํด๋ณด๋ ค๊ณ ํฉ๋๋ค.
๊ธฐํ๊ฐ ๋๋ค๋ฉด ๋ค์ ํฌ์คํ ์ ์์ฑํ๊ฒ ์ต๋๋คโฆใ ใ ,,,
๊ทธ๋ฆฌ๊ณ ์ด๋ฒ ๊ธฐํ์ react ์คํ์์ค๋ฅผ ๋ง์ด ์ดํด๋ณด์๋๋ฐ, (๋ฌผ๋ก ๋๋ฌด ๋ง์์ ์์ง ๋ฐ๋ ๋ชป ๋ณธ ๊ฒ ๊ฐ์ง๋งโฆ.) ๋๊ท๋ชจ ์คํ ์์ค๋ฅผ ์ด๋ ๊ฒ ์ ์์ผ๋ก ์ด์ด๋ณด๊ณ ๋ถ์ํด๋ณธ ๊ฒฝํ์ด ๋ป๊น๊ฒ ๋๊ปด์ก์ต๋๋ค.
๋ฌผ๋ก ์๊ฐ์ด ๋~~๋ฌด ๋ง์ด ๊ฑธ๋ฆฌ๊ธด ํ์ง๋งโฆ ์์ผ๋ก๋ ์ข
์ข
์ด๋ฐ ์์ผ๋ก ๊ณต๋ถํด๋ณด๊ณ ์ถ์ต๋๋ค ๐
https://github.com/facebook/react
https://ko.legacy.reactjs.org/docs/introducing-jsx.html
https://ko.legacy.reactjs.org/docs/rendering-elements.html
https://velog.io/@sa02045/React-createElement-์์๋ณด๊ธฐ
https://velog.io/@suyeon9456/Babel
https://velog.io/@tngusglaso/React-react-dom์-๋ํด-์ดํดํ๊ธฐ