jQuery to React
업데이트: React 0.13에 맞춰 수정했습니다. (2015년 5월 14일)
React는 Facebook에서 만든 자바스크립트 UI 라이브러리입니다. 간단한 jQuery 코드를 React 앱으로 조금씩 바꿔가면서 React에 대한 이해를 돕는 것이 이 글의 목표입니다. 맛보기 정도로 생각해 주시기 바랍니다. Step by step from jQuery to Backbone에서 아이디어를 차용했습니다.
시작하기에 앞서 예제로 사용할 마크업 및 jQuery 코드를 살펴봅시다.
<body>
<div class="new-status">
<h2>New monolog</h2>
<form action="">
<textarea></textarea><br>
<input type="submit" value="Post">
</form>
</div>
<div class="statuses">
<h2>Monologs</h2>
<ul></ul>
</div>
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script>
$(document).ready(function() {
$('.new-status form').submit(function(e) {
e.preventDefault();
$.ajax({
url: '/status',
type: 'POST',
dataType: 'json',
data: { text: $('.new-status').find('textarea').val() },
success: function(data) {
$('.statuses').append('<li>' + data.text + '</li>');
$('.new-status').find('textarea').val('');
}
});
});
});
</script>
</body>
다음과 같은 기능을 구현한 꽤나 평범한 코드입니다.
- 글 내용을 입력할 수 있는 칸이 있습니다.
- 버튼을 누르면 입력한 내용을 서버에 보냅니다.
- 요청이 성공하면 목록에 추가한 글을 덧붙이고 입력창의 내용을 비웁니다.
첫 걸음
React 라이브러리 파일을 불러오고, 마크업을 React에서 사용하는 일종의 템플릿 언어인 JSX 형식으로 바꿉니다.
<body>
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script src="http://fb.me/react-0.13.3.js"></script>
<script src="http://fb.me/JSXTransformer-0.13.3.js"></script>
<script type="text/jsx">
React.render(
<div className="app">
<div className="new-status">
<h2>New monolog</h2>
<form action="">
<textarea /><br />
<input type="submit" value="Post" />
</form>
</div>
<div className="statuses">
<h2>Monologs</h2>
<ul></ul>
</div>
</div>
, document.body);
$(document).ready(function() {
// 아까 코드 그대로
});
</script>
</body>
JSX를 사용하면 자바스크립트 코드와 HTML 코드를 섞을 수 있게 됩니다. JSX 코드는 자바스크립트 코드로 변환됩니다. 예를 들어 <a href="http://example.com/"><b>Link</b></a>
는 React.createElement('a', {href: "http://example.com/"}, React.createElement('b', null, "Link"))
로 바뀝니다.
React와 함께 포함시킨 JSXTransformer가 이러한 변환 작업을 해줍 니다. 자동으로 type="text/jsx"
인 <script>
태그를 찾아서 자바스크립트 코드로 컴파일됩니다.
JSX는 HTML과 비슷하긴 하지만 약간 다릅니다. 다소 헷갈릴 수도 있지만 몇가지 사항만 주의하면 됩니다. 처음의 HTML 마크업과 달라진 부분을 살펴봅시다.
- 한번 열린 태그는 반드시 닫아야 합니다:
<br>
과<input>
이<br />
,<input />
으로 바뀌었습니다. - 일부 속성의 이름이 다릅니다:
class
가className
으로 바뀌었습니다. (전체 목록) - 최상위 노드가 필요합니다: 따라서
<div className="app">
으로 한번 감쌌습니다.
React.render
함수는 첫번째 인자로 받은 JSX 코드를 두번째 인자의 DOM 노드에 출력해줍니다. 여기서는 document.body
, 즉 <body>
태그에 마크업을 출력했습니다.
컴포넌트
React가 제공하는 가장 중요한 기능은 컴포넌트입니다. 컴포넌트를 통해 UI 요소를 추상화하고 조립할 수 있게 됩니다. 말로 설명하면 어려우니 코드를 보겠습니다.
var NewStatus = React.createClass({
render: function() {
return <div className="new-status">
<h2>New monolog</h2>
<form action="">
<textarea /><br />
<input type="submit" value="Post" />
</form>
</div>;
}
});
var App = React.createClass({
render: function() {
return <div className="app">
<NewStatus />
<div className="statuses">
<h2>Monologs</h2>
<ul></ul>
</div>
</div>;
}
});
React.render(<App />, document.body);
$(document).ready(function() {
// 아까 코드 그대로
});
앱 전체를 App
컴포넌트에 집어넣고, 글 입력 폼을 NewStatus
컴포넌트로 분리했습니다. React.createClass
함수로 컴포넌트를 선언하고, render 메소드에서 JSX 코드를 리턴하는 것을 알 수 있습니다.
DOM ready 이벤트 없애기
이제는 jQuery를 쓰던 부분을 하나씩 없애보겠습니다. 먼저 $(document).ready(...)
를 없애볼까요?
var NewStatus = React.createClass({
render: function() {
// 아까 코드 그대로
},
componentDidMount: function() {
$('.new-status form').submit(function(e) {
e.preventDefault();
$.ajax({
url: '/status',
type: 'POST',
dataType: 'json',
data: { text: $('.new-status').find('textarea').val() },
success: function(data) {
$('.statuses').append('<li>' + data.text + '</li>');
$('.new-status').find('textarea').val('');
}
});
});
}
});
...
//$(document).ready(function() {
// ...
//});
NewStatus
컴포넌트의 componentDidMount 메소드로 DOM ready 이벤트 핸들러의 내용을 옮겼습니다. componentDidMount 메소드는 DOM 노드가 실제로 문서에 추가된 이후에 호출되므로, 이전 코드와 같은 동작입니다.