January 20, 2019 โข โ๏ธ 7 min read
const element = <div>Hello world</div>;
React๋ฅผ ์ฒ์ ์ ํ ๋, ๋ณดํต์ ์๋ฐ์คํฌ๋ฆฝํธ์๋ ๋ค๋ฅธ ๋ฌธ๋ฒ์ ๋ณผ ์ ์๋ค. ์ ์ฝ๋๋ฅผ ๋ณด๋ฉด ๋ณ์์ <div>Hello world</div>
๋ฅผ ํ ๋นํ๊ณ ์๋๋ฐ ์ด๋ ๋ฌธ์์ด๋ ์๋๊ณ , HTML๋ ์๋๋ค. ๋ฐ๋ก JSX๋ค.
JSX๋ JS + XML์ ์ค์๋ง๋ก์จ ์๋ฐ์คํฌ๋ฆฝํธ ์์์ <div>hello world</div>
์ ๊ฐ์ด HTML ๊ฐ์ด ์๊ธด XML ๋ฌธ๋ฒ์ ์ฌ์ฉํ ์ ์๋ ์๋ฐ์คํฌ๋ฆฝํธ์์ ํ์ฅ๋ ํ์ผํ์์ด๋ค. ๋๋ React์ JSX๋ฅผ ์ฒ์ ๋ณด๊ณ ์ ๋ง ์ฐธ์ ํ๋ค๊ณ ์๊ฐํ๋ค. UI์ ํด๋นํ๋ HTML๊ณผ ๋ก์ง์ ํด๋นํ๋ Javascript๋ฅผ ๋๋์ง ์๊ณ JSX๋ผ๋ ํ์ผํ์์ ์ฐฝ์กฐํ์ฌ ์ปดํฌ๋ํธ ๋จ์๋ก UI์ ๋ก์ง์ ํ ํ์ผ์ ํฉ์ณค๊ธฐ ๋๋ฌธ์ด๋ค.
๋ฌผ๋ก React์์ JSX๋ฅผ ์ฌ์ฉํ์ง ์์ ์ ์๋ค. ํ์ง๋ง, Javascript ์ฝ๋ ์์์ UI๊ฐ ๋์ํ๋ ๊ฒ์ ์๊ฐ์ ์ผ๋ก ๋ฐ๋ก ๋ณผ ์ ์๊ธฐ ๋๋ฌธ์ ๋ง์ ์ฌ๋๋ค์ด ์ฌ์ฉํ๋ค.
๋ค์์ React์์ JSX์ ์์ ์ด๋ค.
class AwesomeComponent extends React.Component {
render() {
return (
<MyButton color="blue" shadowSize={2}>
Click Me
</MyButton>
);
}
}
์ JSX ์ฝ๋๋ ์๋์ ๊ฐ์ด ์ปดํ์ผ๋๋ค.
class AwesomeComponent extends React.Component {
render() {
return React.createElement(
MyButton,
{ color: "blue", shadowSize: 2 },
"Click Me"
);
}
}
์จ๋ผ์ธ ๋ฐ๋ฒจ ์ปดํ์ผ๋ฌ์์ ์ ๋ด์ฉ์ ํ์ธํ ์ ์๋ค.
XML ํ์์ ์ฝ๋๋ React.createElement
ํจ์๋ฅผ ํธ์ถํ๋ ์ฝ๋๋ก ์ปดํ์ผ๋๊ธฐ ๋๋ฌธ์ React๋ฅผ ์ง์ ์ฐ์ง ์๋๋ผ๋ React๋ฅผ ์ํฌํธํด์ฃผ์ด์ผ ํ๋ค.
import React from 'react';
import AwesomeButton from './AwesomeButton';
function BlueButton() {
// return React.createElement(AwesomeButton, {color: 'blue'}, null);
return <AwesomeButton color="blue" />;
}
React.createElement
ํจ์์ ์ธ์๋ React.createElement(component, props, ...children)
์ ๊ฐ๋ค. ์ฒซ๋ฒ์งธ ์ธ์์ component๊ฐ ์ค๊ณ , ๋๋ฒ์งธ์๋ Object
ํ์์ props๊ฐ ์ค๊ณ ์ธ๋ฒ์งธ ์ธ์๋ ๊ฐ๋ณ์ธ์๋ก children๋ค์ด ์จ๋ค. ์ฌ๊ธฐ์ ์ค์ํ๊ฒ ๋ด์ผํ ์ ์ ์ต์์ ๋ถ๋ชจ DOM์ด๋ค. ์ต์์์์ ์ ์ผ ์ฒ์ ํธ์ถ๋๋ React.createElement
๋ ๋จ ํ๋๋ง์ด ํธ์ถ๋๊ธฐ ๋๋ฌธ์ ์ต์์ ๋ถ๋ชจ DOM์ ์ค๋ก์ง ํ๋์ฌ์ผ ํ๋ค.
// ๋์ ์: ์ต์์ ๋ถ๋ชจ DOM์ด ๋ ๊ฐ์ด๋ค. ์ปดํ์ผํ ์ ์๋ค.
function BadComponent() {
return (
<div>hello</div>
<div>world</div>
);
}
// ์ข์ ์: ์ต์์ ๋ถ๋ชจ DOM์ด ํ ๊ฐ์ด๋ค.
function GoodComponent() {
return (
<div>
<div>hello</div>
<div>world</div>
</div>
);
}
// ์ GoodComponent.jsx๋ฅผ ์ปดํ์ผํ GoodComponent.js
function GoodComponent() {
return React.createElement(
"div",
null,
React.createElement(
"div",
null,
"hello"
),
React.createElement(
"div",
null,
"world"
)
);
}
React๋ ์๋ฌธ์๋ก ์์ํ๋ ์ปดํฌ๋ํธ๋ฅผ HTML tag๋ก ์ธ์งํ๊ธฐ ๋๋ฌธ์ ๋๋ฌธ์๋ก ์์ํ๋ ๋ค์ด๋ฐ์ ์ฌ์ฉํด์ผ ํ๋ค. ์ด๋ ๋ณดํต ํด๋์ค๋ ๋๋ฌธ์๋ก ์์ํ๋๊ฒ ๊ด์ต์ด๋ฏ๋ก ์ ๊ฒฝ์ฐ์ง๋ ์์๋ ๋ ๋ฏ ์ถ๋ค.
props๋ฅผ Object
type์ผ๋ก ์ ์ํ์ฌ <Greeting {...props} />
์ ๊ฐ์ด ์ฌ์ฉํ ์ ์๋ค. ๋ถ๋ชจ ์ปดํฌ๋ํธ์ props๋ฅผ ์์ ์ปดํฌ๋ํธ์์ ๊ทธ๋๋ก ์์ ์ปดํฌ๋ํธ์๊ฒ ๋ฌผ๋ ค์ค ๋ ์ ์ฉํ๊ฒ ์ฌ์ฉํ ์ ์๋ค.
function App1() {
return <Greeting firstName="Ben" lastName="Hector" />;
}
function App2() {
const props = {firstName: 'Ben', lastName: 'Hector'};
return <Greeting {...props} />;
}
๋ฐฐ์ด์ ์๋ ์์ดํ
์ ์ฐจ๋ก๋๋ก <li></li>
๋ก ๋ณด์ฌ์ฃผ๊ณ ์ถ์ ๋ Javascript์ map
์ ์ฌ์ฉํ๋ฉด ์ฝ๊ฒ ์ฒ๋ฆฌํ ์ ์๋ค.
function TodoList() {
const todoItems = ['You don\'t know JS ์ฑ
์ฝ๊ธฐ', '๊นํ ์ปค๋ฐํ๊ธฐ', '๋ธ๋ก๊ทธ ํฌ์คํ
ํ๊ธฐ'];
return (
<ul>
{todoItems.map((item, index) => <li key={index}>{item}</li>)}
</ul>
);
}
true
, false
undefined
, null
์ ๋ ๋๋์ง ์๊ธฐ ๋๋ฌธ์ ์ด ํน์ง์ ์ฌ์ฉํ์ฌ ์๋์ ๊ฐ์ด ์ธ ์ ์๋ค.
// ์ข์ ์
<div>
{showHeader && <Header />}
<Content />
</div>
/* NOPE. ํ์ง๋ง ์๋์ ๊ฐ์ด ์ฌ์ฉํ๊ฒ ๋๋ฉด props.messages.length์ด 0์ผ ๋
falsyํ ๊ฐ์ผ๋ก ๋ค์ ๊ฐ๋ค์ด ๋์ค์ง ์๊ฒ ์ง๋ง 0์ด ๋ ๋๋๊ธฐ ๋๋ฌธ์ ์ณ์ ๋ฐฉ๋ฒ์ ์๋๋ค. */
<div>
{props.messages.length &&
<MessageList messages={props.messages} />
}
</div>
// OK. ์ด์ ๊ฐ์ด ๋ฐ๊ฟ์ฃผ์ด์ผ ํ๋ค.
<div>
{props.messages.length > 0 &&
<MessageList messages={props.messages} />
}
</div>
React 16.4.0 ๋ฒ์ ์ ์ฝ๋๋ฅผ ์ดํด๋ณด๊ฒ ๋ค. ReactElement.js
ํ์ผ์์ createElement
๋ฅผ ์ ์ํ๋ ์ฝ๋์ด๋ค.
export function createElement(type, config, children) {
// ... ์ค๋ต
return ReactElement(
type,
key,
ref,
self,
source,
ReactCurrentOwner.current,
props,
);
}
React.createElement
ํจ์๋ ReactElement
๋ผ๋ ์๋ฃํ์ผ๋ก ๋ฐํํ๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
const ReactElement = function(type, key, ref, self, source, owner, props) {
const element = {
// This tag allows us to uniquely identify this as a React Element
$$typeof: REACT_ELEMENT_TYPE,
// Built-in properties that belong on the element
type: type,
key: key,
ref: ref,
props: props,
// Record the component responsible for creating this element.
_owner: owner,
};
// ... ์ค๋ต
return element;
};
์ ์ฝ๋๋ฅผ ํตํด ReactElement
์๋ฃํ์ $$typeof
, type
, key
, ref
, props
, _owner
๋ฅผ ๊ฐ๋ Object
์ธ ๊ฒ์ ํ์ธํ ์ ์๋ค.
class AwesomeComponent extends React.Component {
render() {
return React.createElement(
MyButton,
{ color: "blue", shadowSize: 2 },
"Click Me"
);
}
}
๋ฐ๋ผ์ ์์์ JSX๊ฐ ์ปดํ์ผ๋ ์ฝ๋๋ ์๋์ ๊ฐ์ด ๋ค์ ReactElement
๋ก ๋ฐํ๋ ๊ฒ์ด๋ค.
class AwesomeComponent extends React.Component {
render() {
return {
type: MyButton,
props: {
color: 'blue',
shadowSize: 2,
children: 'Click Me'
}
}
}
}
React์์ ๊ฐ์ฅ ์ค์ํ ๊ฐ๋ ์ธ Component๋ UI๋ฅผ ๊ตฌ์ฑํ๋ ๊ฐ๋ณ์ ์ธ ๋ทฐ ๋จ์์ด๋ค. React๋ก ๊ฐ๋ฐํ๋ค๋ ๊ฒ์ ๋ธ๋ก์ ์กฐํฉํด ์ง์ ์ง๋ ๊ฒ๊ณผ ๊ฐ๋ค. React ์ฑ์ Component๋ค์ ๊ฒฐํฉ์ผ๋ก ๋ง๋ค์ด์ง๋ ๊ฒ์ด๋ค. ์ฌ๊ธฐ์ ์ฃผ์ ๊น๊ฒ ๋ด์ผํ ๋ถ๋ถ์ Component๊ฐ ์ฌ์ฌ์ฉ์ด ๊ฐ๋ฅํ๋ค๋ ์ ์ด๋ค. ์ฌ์ฌ์ฉ์ด ๊ฐ๋ฅํ React์ Component๋ ์์ฐ์ฑ์ ๊ทน๋ํ์์ผ์ฃผ์๋ค. Component๋ฅผ ํจ์จ์ ์ผ๋ก ๋ง๋ค๊ธฐ ์ํด React๋ JSX๋ผ๋ ํน์ดํ Syntax๋ฅผ ๋ง๋ค์ด๋๊ณ ๊ทธ ๊ฒฐ๊ณผ๋ ํ์ํ๋ค. Javascript ์ฝ๋ ์์ ํ๊ทธ๋ฅผ ๋ฃ์ด ์ฌ์ฉํ๋ค๋ ์๊ฐ์ ์ ๋ง๋ก ๋ฐ์์ ์ ํ์ด์๋ค. ์ ๋ง ๋ฏธ์น ๊ฒ ๊ฐ๋ค.
์ถ๊ฐ์ ์ผ๋ก React์ ๋ ํ๋์ ๊ฐ์ฅ ์ค์ํ ํน์ง์ธ Virtual DOM์ ๋นผ๋์ ์ ์๊ฒ ๋ค. ์๋ง ๋ค์ ํฌ์คํธ ์ฃผ์ ๊ฐ ๋ ๊ฒ ๊ฐ๋ค. ๐ฅ
Personal blog by Jon Jee.
I hope to explain with words and code.