1. 시작하기
React 앱 생성 시작하도록 하겠습니다.
create-react-app 은 이름과 같이, React 앱을 만들어주는 도구입니다. 터미널에 다음과 같이 CRA(Create React App)를 설치합니다.
npm install -g create-react-app
npx create-react-app react-base
> npx란,
npx는 npm >= 5.2.0 에서 사용할 수 있는 패키지 매니저입니다.
npm의 경우, -g 옵션을 통해 같은 모듈을 공유해서 사용할 수 있지만, 최신 버전으로 재설치 하지않으면 모듈의 업데이트 상태를 확인할 수 없습니다.
업데이트를 진행 했을 때 변동사항이 생겨 다른 프로젝트에도 영향을 끼칠 수 있습니다.
npx는 모듈을 로컬에 저장하지 않고, 매번 최신 버전의 파일을 임시로 불러와 실행 시킨 후, 다시 그 파일은 없어지는 방식으로 모듈이 작동하고 있습니다.
따라서 CRA와 같은 보일러 플레이트 모듈에 효과적입니다. CRA를 설치할 때 마다 매번 최신 버전만 가져와서 설치해 주기 때문에 지금 어떤 버전을 사용하고 있는지 신경 쓸 필요가 없습니다.
2. 프로젝트 구조
CRA 후 생성된 프로젝트입니다.
my-app/
README.md
node_modules/
package.json
public/
index.html
favicon.ico
src/
App.css
App.js
App.test.js
index.css
index.js
logo.svg
위와 같은 구조로 생성되며,
public/index.html
는 페이지 템플릿,
src/index.js
는 JavaScript 시작점입니다.
Webpack은 빠른 처리를 위해 /src
하위 폴더에만 작업에 관여합니다.
따라서 JS나 CSS와 같은 파일은 /src
폴더 하위에 위치하는 것이 올바릅니다.
3. 렌더링
생성된 html
파일 (index.html
) 어딘가에 <div>
태그가 있을 것 입니다.
<div id='root'></div>
이 안에 들어가는 모든 엘리먼트를 React DOM에서 관리하기 때문에 이것을 “루트(root)” DOM 노드라 부릅니다.
React로 구현된 애플리케이션은 일반적으로 하나의 루트 DOM노드가 있습니다.
React를 기존 앱에 통합하려는 경우 원하는 만큼 많은 수의 독립된 루트 DOM노드가 있을 수 있습니다.
React 엘리먼트를 루트 DOM 노드에 렌더링하려면 ReactDOM.render()로 전달하면 됩니다..
const element = <h1> hello, world </h1>
ReactDOM.render(element, document.getElementById('root'));
src/index.js
import React from 'react';
import ReactDom from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
ReactDOM.render(<App />, document.getElementById('root'));
serviceWorker.unregister();
> ReactDOM.render ?
이 코드는 컴포넌트를 페이지에 렌더링하는 역할을 하며, react-dom 모듈을 불러와 사용할 수 있습니다. 첫번째 파라미터에는 렌더링 할 내용을 JSX 형태로 작성하고, 두번째 파라미터는 렌더링 할 document 내부 요소를 설정합니다. 여기서는 id가 root인 요소 안에 렌더링을 하도록 설정했는데, public/index.html 파일을 열어보면 확인할 수 있습니다.
> 렌더링 된 엘리먼트 업데이트 하기
React 엘리먼트는 불변객체입니다. 앨리먼트를 생성한 이후, 해당 엘리먼트의 자식이나 속성을 변경할 수 없습니다.
따라서, UI를 업데이트하는 유일한 방법은 새로운 엘리먼트를 생성하고, 이를 ReactDOM.render()로 전달하는 것입니다.
예시로 똑딱거리는 시계를 구현할 때,
function tick() {
const element = (
<div>
<h1>Hello, world!</h1>
<h2>It is {new Date().toLocaleTimeString()}.</h2>
</div>
);
ReactDOM.render(element, document.getElementById('root'));
}
setInterval(tick, 1000);
setInterval() 콜백을 이용해 초마다 ReactDOM.render()를 호출합니다.
※ 실제로 대부분의 React앱은 ReactDOM.render()를 한 번만 호출합니다.
React 개발 환경 구축을 위해 개념들을 하나씩 보도록 하겠습니다.
4. JSX
JSX는 자바스크립트의 확장 문법이며, XML과 매우 흡사합니다.
이런식으로 작성된 코드는 브라우저에서 실행되기 전에 코드가 번들링되는 과정에서 바벨을 사용하여 일반 자바스크립트 형태의 코드로 변환됩니다.
function App(){
return {
<div>
Hello <b> react </b>
</div>
}
}
위의 코드는 다음과 같이 변환됩니다.
function App(){
return React.createElement("div", null, "hello", React.createElement("b",null,"react"));
}
만약 컴포넌트를 렌더링할 때마다 JSX 코드를 작성하는 것이 아니라 위 코드처럼 매번 React.createElement() 함수를 사용해야 한다면 매우 불편할 것 입니다.
JSX를 사용하면 매우 편하게 UI를 렌더링할 수 있습니다.
> JSX에 표현식 포함하기
const user = {
firstName:"ShinJong",
lastName:"Park"
}
const element = <h1>Hello, {user.firstName}</h1>;
ReactDOM.render(
element,
document.getElementById('root')
);
-
JSX의 중괄호 안에 유효한 모든 JavaScript 표현식을 넣을 수 있습니다.
-
다음과 같이 if 구문 및 for loop 안에 사용할 수 있다.
function getGreeting(user){
if(user){
return <h1>Hello, {user.firstName}</h1>
}
return <h1>HEllo, Stranger.</h1>
}
const element = getGreeting(user)
- 중괄호를 사용하여 Attribute에 Javascript 표현식을 삽입할 수 있다.
const element = <img src={user.avatarUrl}></img>
> JSX는 객체를 표현합니다.
- Babel은 JSX를 React.createElement() 호출로 컴파일합니다.
아래의 두 예시는 동일합니다.
const element = (
<h1 className="greeting">
Hello, world!
</h1>
);
const element = React.createElement(
'h1',
{className: 'greeting'},
'Hello, world!'
);
React.createElement()는 버그가 없는 코드를 작성하는데 도움이 되도록 몇가지 검사를 수행하며, 기본적으로 다음과 같은 객체를 생성합니다.
const element = {
type: 'h1',
props: {
className: 'greeting',
children: 'Hello, world!'
}
};
이러한 객체를 “React Element”라고 하며, 이를 화면에 표시하려는 항목에 대한 설명이라고 생각할 수 있습니다.
React는 이러한 객체를 읽은 후 DOM을 구성하고 최신으로 유지하는데 이러한 객체를 사용합니다.