JavaScript를 사용하여 HTML로 구성한 UI를 제어해보았다면 DOM을 변형시키기 위해선 DOM Selector API를 사용해서 특정 DOM을 선택한 뒤, 특정 이벤트가 발생하면 변화를 주었다.
그러나 사용자와의 인터랙션이 별로 없는 웹페이지라면 상관없겠지만, 만약 인터렉션이 자주 발생하고 이에 따라 동적으로 UI를 표현해야된다면, 이러한 규칙이 다양해지고 관리하기도 힘들어질것입니다. 대부분의 경우 웹 애플리케이션의 규모가 커지면, 처리해야할 이벤트도 다양해지고, 관리해야 할 상태값도 다양해지고 DOM도 다양해지게 된다면 코드가 난잡해지고 복잡한 웹이 될 것입니다.
이에 Ember, Backbone, AngulaJS등 다양한 프레임워크가 만들어졌었는데 이 프로임워크들은 자바스크립트의 특정 값이 바뀌면 특정 DOM의 속성이 바뀌도록 연결을 해주어서, 업데이트 하는 작업을 간소화해주는 방식으로 웹개발의 어려움을 해결해주었습니다.
하지만 리액트의 경우에는 조금 다른 발상에서 만들어졌습니다. 리액트는 어떠한 상태가 바뀌었을때, 그 상태에 따라 DOM을 어떻게 업데이트 할 지 규칠을 정하는 것이 아니라, 아예 다 날려버리고 처음부터 새로 만들어서 보여준다면 어떨까? 라는 아이디어에서 개발이 시작되었습니다. 그러면 업데이트를 어떻게 해야 할 지 에 대한 고민을 전혀 안해도 되기 떄문에 개발이 정말 쉬워질 것입니다. 하지만 정말로 동적인 UI를 보여주기 위해서 모든걸 다 날려버리고 새로 만들게 된다면 , 속도가 굉장히 느릴 것입니다. 작은 웹애플리케이션이라면 상관없겠지만 큰 웹앱플리케이션이라면 상상도 할 수 없는 일입니다.
하지만, 리액트는 Vurtual DOM을 사용해서 이를 가능케 했습니다.
Virtual DOM은 가상의 DOM으로써 브라우저에서 실제로 보여지는 DOM이 아니라 메모리에 가상으로 존재하는 DOM으로서 단순 JavaScript 객체이기 때문에 작동 성능이 실제로 브라우저에서 DOM을 보여주는 것 보다 속도가 훨씬 빠릅니다. 리액트는 상태가 업데이트 되면, 업데이트가 필요한 곳의 UI를 Virtual DOM을 통해서 렌더링합니다. 그리고 나서 리액트는 실제 브라우저에 보여지고 있는 DOM과 비교를 한 후, 차이가 있는 곳을 감지하여 이를 실제 DOM에 패치 시켜줍니다. 이를 통하여, "업데이트를 어떻게 할 지"에 대한 고민을 하지 않으면서, 빠른 성능도 지켜낼 수 있게 되었습니다.
JSX의 기본규칙 알아보기
JSX는 리액트에서 생김새를 정의할 떄, 사용하는 문법입니다. 얼핏보면 HTML과 같이 생겼지만 실제로는 JavaScript 입니다.
return <div> 안녕하세요 </div>;
리액트 컴포넌트 파일에서 XML형태로 코드를 작성하면 babel이 JSX를 JavaScript로 변환을 해줍니다.
여기서 Babel은 자바스크립트의 문법을 확장해주는 도구입니다. 아직 지원되지 않는 최신 문법이나, 편의상 사용하거나 실험적인 자바스크립트 문법들을 정식 자바스크립트 형태로 변호나해줌으로써 구형 브라우저 같은 환경에서도 제대로 실행 할 수 있게 도와주는 역할을 합니다.
JSX가 JavaScript로 제대로 변환이 되려면 지켜주어야 하는 몇가지 규칙들을 살펴보겠습니다.
태그는 꼭 닫혀있어야 합니다.
다음과 같은 코드는 오류가 발생하게 됩니다.
import React from 'react';
import Hello from './Hello';
function App() {
return (
<div>
<Hello />
<Hello />
<Hello />
<div>
</div>
);
}
export default App;
또한 HTML에서는 input
또는 br
태그를 사용 할 때 닫지 않고 사용하기도 합니다. 하지만 리액트에서는 그렇게 하면 안됩니다. <Hello />
와 같이 Self Closing 태그를 사용해주는 방법도 있습니다.
두개 이상의 태그는 무조건 하나의 태그로 감싸져있어야 합니다.
import React from 'react';
import Hello from './Hello';
function App() {
return (
<Hello />
<div>안녕히계세요.</div>
);
}
export default App;
그 대신 하나의 태그로 감싸주어야 합니다.
import React from 'react';
import Hello from './Hello';
function App() {
return (
<div>
<Hello />
<div>안녕히계세요</div>
</div>
);
}
export default App;
하지만, 이렇게 단순히 감싸기 위해서 불필요한 div를 사용하기 싫다면 아래와 같이 Fragment를 사용 할 수도 있습니다.
import React from 'react';
import Hello from './Hello';
function App() {
return (
<>
<Hello />
<div>안녕히계세요</div>
</>
);
}
export default App;
태그 작성 할 때 이름 없이 작성을 하게 되면 Fragment가 만들어지는데, Fragment는 브라우저 상에서 따로 별도의 엘리먼트로 나타나지 않습니다.
JSX 내부에 자바스크립트 변수를 보여줘야 할 때에는 {}
로 감싸서 보여줍니다.
return (
<>
<Hello />
<div>{name}</div>
</>
);
JSX에서 태그에 style
과 CSS class를 설정하는 방법은 HTML에서 설정하는 방법과 다릅니다.
우선, 인라인 스타일은 객체 형태로 작성을 해야 하며, background-color
처럼 - 로 구분되어 있는 이름들은 backgroundColor
처럼 camelCase 형태로 네이밍 해주어야 합니다. 또한, CSS class 를 설정 할 때에는 class= 가 아닌 className= 으로 설정을 해주어야 합니다.
import React from 'react';
import Hello from './Hello';
import './App.css';
function App() {
const name = 'react';
const style = {
backgroundColor: 'black',
color: 'aqua',
fontSize: 24, // 기본 단위 px
padding: '1rem' // 다른 단위 사용 시 문자열로 설정
}
return (
<>
<Hello />
<div style={style}>{name}</div>
<div className="gray-box"></div>
</>
);
}
export default App;
JSX 내부의 주석은 {/* 이런 형태로 */}
작성합니다.
추가적으로, 열리는 태그 내부에서는 // 이런 형태로도 주석 작성이 가능합니다.