목표
- Vanilla js에서 React로 자연스럽게 넘어가는 방법을 알아본다.
- JSX 문법에 대해 알아본다.
<!DOCTYPE html>
<html lang="ko">
<body>
<div id="root"></div>
<script>
const rootElement = document.getElementById("root");
const element = document.createElement("h1");
element.textContent = "Hello, World";
rootElement.appendChild(element);
</script>
</body>
</html>
CDN 이란?
- 웹에서 사용되는 다양한 컨텐츠(리소스)를 저장하요 제공하는 시스템을 말한다.
<!DOCTYPE html>
<html lang="ko">
<head>
<script
crossorigin
src="https://unpkg.com/react@17/umd/react.development.js"
></script>
<script
crossorigin
src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"
></script>
</head>
<body>
<div id="root"></div>
<script>
const rootElement = document.getElementById("root");
// const element = React.createElement("h1", { children: "Hello, world" });
const element = React.createElement("h1", null, "Hello World");
ReactDOM.render(element, rootElement);
</script>
</body>
</html>
React.createElement(
type,
[props],
[...children]
)
DOM(Document Object Model) 이란?
- 메모리에 웹 페이지 문서 구조를 표현함으로써 스크립트 및 프로그래밍 언어와 페이지를 연결한다.
- DOM은 문서를 논리 트리로 표현한다.
- 이를 통해 문서의 구조, 스타일, 콘텐츠를 변경할 수 있다.
- 즉, Element는 우리 눈에 보여지는 것이고 DOM은 컴퓨터(브라우저)가 이해하는 엘리멘트의 원형이라고 생 각할 수 있다.
🤔 의문
- 바닐라 js로 엘리멘트를 생성하는 것과 React의 createElement로 엘리멘트를 생성 하는 것은 별 차이 없어 보였고 굳이 사용하는 이유를 모르겠다.
- 둘 다 엘리먼트를 많이 만들어야 할 때 처럼 createElement 함수를 일일히 다 선언해주는 것은 너무 비효율적이라는 생각이 들었다.
그래서 나온 것인 JSX이다.
const element = <h3>Hello, World</h3>
바벨(babel)이란?
- 자바스크립트 컴파일러이다.
- 컴파일러는 언어 해석기로 특정 언어를 다른 프로그래밍 언어로 옮기는 프로그램을 뜻한다.
// const element = <h3 className="hello">Hello, World</h3>
"use strict";
const element = /*#__PURE__*/React.createElement("h3", {
className: "hello"
}, "Hello, World");
<!DOCTYPE html>
<html lang="ko">
<head>
<script
crossorigin
src="https://unpkg.com/react@17/umd/react.development.js"
></script>
<script
crossorigin
src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"
></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
const rootElement = document.getElementById("root");
const element = <h1 className="hello">hello, world</h1>;
ReactDOM.render(element, rootElement);
</script>
</body>
</html>
💡 주의
- 자바스크립트가 이해하는 script와 바벨이 이해하는 script가 다르기 때문에 위의 코드 처럼 script 태그 안에 type="text/babel"을 넣어 주어야 한다.
<body>
<div id="root"></div>
<script type="text/babel">
const rootElement = document.getElementById("root");
const text = "hello, world";
const className = "hello";
const element = <h1 className={className}>{text}</h1>;
ReactDOM.render(element, rootElement);
</script>
</body>
<body>
<div id="root">
<h1>First child</h1>
<h2>second child</h2>
<h3>third child</h3>
</div>
</body>
<body>
<div id="root"></div>
<script type="text/babel">
const rootElement = document.getElementById("root");
const element = (
<div
className="children"
children={[
React.createElement("h1", null, "First child"),
React.createElement("h2", null, "Second child"),
React.createElement("h3", null, "Third child")
]}
/>
);
ReactDOM.render(element, rootElement);
</script>
</body>
🤔 의문
- 바닐라 js로 엘리멘트를 생성할 때에는 root div 태그에 생성되었는데 React로 엘리멘트를 생성할 때에는 필요없는 div 태그를 하나 더 생성했는데 비효율 적이다.
그래서 리액트에서 Flagment라는 것을 만들었다.
const element = (
<React.Fragment
className="children"
children={[
React.createElement("h1", null, "First child"),
React.createElement("h2", null, "Second child"),
React.createElement("h3", null, "Third child")
]}
/>
);
const element = (
<>
<h1>First child</h1>
<h2>Second child</h2>
<h3>Third child</h3>
</>
);
const print = (number, gender) => (
<>
<h1>{number} child</h1>
<h2>{gender}</h2>
</>
);
const element = (
<>
{print("First", "man")}
{print("Second", "woman")}
{print("Third", "man")}
</>
);
const Print = ({ number, gender }) => {
return (
<>
<h1>{number} child</h1>
<h2>{gender}</h2>
</>
);
};
const element = (
<>
<Print number="First" gender="man" />
<Print number="Second" gender="woman" />
<Print number="Third" gender="man" />
</>
);
💡 주의
- JSX 문법을 사용해 엘리먼트를 생성할 때에는 무조건 첫 글자를 대문자로 시작하여야 한다. 소문자를 사용하게 되면 기존 html 태그들과 혼동이 발생할 수 있기 때문에 명시적으로 React에서 만들어 놓은 규칙이다.
- 실제로 아래와 같은 에러가 발생한다.
const Print = ({ number, gender, children }) => {
return (
<>
<h1>{number} child</h1>
<h2>{gender}</h2>
{children}
</>
);
};
const element = (
<>
<Print number="First" gender="man">
<h3>My name is Biber</h3>
</Print>
<Print number="Second" gender="woman" />
<Print number="Third" gender="man" />
</>
);
const Text = ({ text }) => {
if (text.charAt(0) === text.charAt(0).toUpperCase()) {
return <h1>{text}</h1>;
} else {
return <h2>{text}</h2>;
}
};
const element = (
<>
<Text text="UpperCase" />
<Text text="lowercase" />
</>
);
const Text = ({ text }) => {
return text.charAt(0) === text.charAt(0).toUpperCase() ? (
<h1>{text}</h1>
) : (
<h2>{text}</h2>
);
};
const Number = ({ number }) => {
return number % 2 !== 0 ? <h1>{number}</h1> : <h2>{number}</h2>;
};
const numberArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const element = (
<>
{numberArray.map((number) => (
<Number key={number} number={number} />
))}
</>
);