관련 글
서론
최근까지 웹 개발을 할 때에 Python Flask와 Jinja Template을 이용해 간단하게 개발을 해 왔었다. 그러다보니 Flask API와 Template Jquery로 이루어진 Javascript 파일들이 난잡하게 어질러 져 있어 직접 개발을 하고도 너무 더럽다 라는 생각이 많이 들었었다.
그러다가 React JS라는 것을 알게 되었고 이를 이용해 웹 개발을 하다보니 정리가 잘되기도 하고 실제 웹을 컨트롤할 때 무척 편하다는 느낌을 받게 되었다.
아직 React JS에 대해서 잘 이해를 못하고 단순히 Doc에 나온대로 사용만 하는 수준이지만 지금까지 해왔던 것들을 정리 및 사람들에게 React JS에 대해 소개도 할 겸 해서 블로그에 글을 올리려고 한다.
또한, 이번 글에서는 간단하게 React JS에 대해 소개만 하고, 이 후 Lifecycle과 Flux 등에 대해 정리할 예정이다. 그리고 그외에 React JS, Python Flask와 Webpack을 이용해 실제 웹 개발을 할 수 있는 환경구축 방법에 대해 작성할 예정이다.
React JS
React JS는 페이스북과 인스타그램의 웹 UI를 개발할 때 사용하려고 만든 자바스크립트 라이브러리
이다. 또한 Backbone.js와 Angular.js와 같이 이를 이용해 웹의 Front를 자유자재로 다룰 수 있으므로 나는 웹 프론트 프레임워크(Web Front Framework)
라고도 생각한다.
React JS의 가장 큰 특징이자 사용하는 이유로는 지속해서 데이터가 변화하는 대규모 에플리케이션을 구축할 수 있다
이다. React에서 Component
를 사용하여 웹 UI를 구축하며 데이터가 변하는 Component만을 다시 rendering해서 변화된 데이터를 표시한다.
React JS는 영어문서와 한글문서가 있으며 링크에서 확인할 수 있다.
React JS의 특징은 크게 세가지가 있다.
JSX(JavaScript XML)
JSX는 React JS에서 확장자 명이기도 하고, JavaScript + XML이라는 뜻을 갖고 있다. 이는 기존 XML을 허용하는 JavaScript 확장 문법으로 JavaScript에 마크업 코드(Markup Code)를 작성할 수 있게 허용한다. 예를 들어, JS 내에서 div DOM을 생성하려면React.createElement('div', {className: "commentBox"}, "Hello World)
와 같이 작성해야 하지만, JSX를 이용하면<div className="commentBox">Hello World</div>
와 같이 사용할 수 있다.
일반 HTML 사용하듯이 사용하면 되므로 무척 편리하다. 하지만 이러한 JSX 파일을 그냥 사용할 수는 없고 JSX Transformer를 include하거나 직접 컴파일을 해야 사용할 수 있다.가상 DOM(Virtual DOM)
실제 HTML의 DOM이 아닌 React에서 사용하는 Virtual DOM이란 것이 존재한다. Virtual DOM에는ReactElement
,ReactElement Factory
,ReactNode
,ReactComponent
그리고ReactComponent Class
가 있다. 자세한 내용은 링크에서 확인 가능하다.단방향 데이터 플로우(Unidirectional Data Flow)
React JS 간단한 예제
원래 실제 React 파일인 *.jsx 파일을 사용하려면 webpack
이나 browserify
같은 것들을 이용해 컴파일을 한 후 로드해서 사용해야 하지만 간단한 예제이므로 babel.js
를 로드하여 즉석에서 컴파일할 수 있게한다.
Example 1
첫 번째로, <head></head>
태그 내에 위의 JS 파일들은 전부 include 해야 한다. 여기서는 jsx 파일을 컴파일 하지 않기 때문에 babel
은 무조건 include 해야 한다.
두 번째로, React js로 만든 DOM을 생성할 div를 하나 만든다. 물론 div가 아닌 body에다가 rendering 할 수도 있다.
세 번째로,
var CommentBox = React.createClass({})
코드를 이용해 하나의 Component
를 만든다. 이 때, Component 이름은 무조건 대문자로 시작하는 Camel case로 하여야 한다.
Example 2
이번 예제는, 여러개의 component를 이용해 DOM을 구성하고 상위 component에서 데이터를 받아 this.props.*
를 통해 접근하여 표시할 수 있는 예제이다. 아래 코드와 같이 React JS에서 Data Flow는 상위 component에서 하위 component로 진행된다.
코드
결과
위의 코드를 보면 ...this.props
를 사용하고 있는데, 이는 상위 component에서 받은 props들을 그대로 하위 component로 넘기겠다는 의미이다. 전부 전달 하는 것 외에도 몇개를 현재 component에서 사용하고 나머지를 넘기는 것도 가능하다.
...
var {checked, ...other} = this.props;
return(
<div {...other} className={test}></div>
);
...
Example 3
this.props
를 이용해 데이터를 전달하고 전달 받는 방법을 알았다. 이번 예제는 this.state
를 이용해 데이터를 변경하고 변경된 component만 re-rendering
하는 방법을 알 수 있는 예제이다.
코드
결과
위의 코드를 실행해 보면, form 태그에 입력하는 그대로 브라우저에 표시되는 것을 볼 수 있다. 이처럼 this.state
를 이용하면 데이터를 변경하고 실시간으로 이를 표시할 수 있다.
위 코드를 자세히 보면, CommentBox
component 내부에 CommentList
, CommentForm
component가 존재한다. 그리고 이 예제에서 하려고 하는 일은 CommentForm
component에서 데이터를 수정하면 그 변화가 CommentList
에 나타날 수 있게 하는 것이다.
그러기 위해선 CommentList
와 CommentForm
의 데이터를 컨트롤 할 수 있는 CommentBox
에 state를 두어야 한다. 먼저 getInitialState
Lifecycle Method를 이용해 초기 state를 초기화 한다.
var CommentBox = React.createClass({
getInitialState: function(){
return {data: this.props.data};
},
이 후 data state를 변경할 dataChange
함수를 만든다. author와 text를 받아오면 기존 state에 데이터를 추가하고 this.setState()
함수를 호출하는 것을 볼 수 있다. React JS에서 this.state를 직접적으로 변경하면 데이터는 변경 되나 rendering이 되지 않아 데이터 변화를 표시할 수 없다. 하지만 this.setState()
함수를 이용하면 state 값을 변경하고 변경된 component를 re-rendering한다.
dataChange: function(author, text){
var tmpData = this.state.data;
tmpData.push({
author: author,
text: text
});
this.setState({data:tmpData});
},
하지만 이 dataChange
함수는 현재 component인 CommentBox
에서 사용할 함수가 아닌 CommentForm
component에서 사용할 함수이다. 그러므로 이 함수를 CommentForm
component에 props로 넘겨준다.
var CommentBox = React.createClass({
...
...
render: function() {
return (
<div className="commentBox">
<h1>Comments</h1>
<CommentList data={this.state.data} />
<CommentForm formHandler={this.dataChange} />
</div>
);
}
});
이제 CommentForm
에서는 form submit 이벤트가 발생하면 input 태그의 값을 가져와 this.props.formHandler
함수를 사용할 함수를 만든다.
var CommentForm = React.createClass({
formOnChange: function(e){
e.preventDefault();
var author = this.refs.author.value;
var text = this.refs.text.value;
if(author!="" && text!=""){
this.props.formHandler(author, text);
this.refs.author.value = '';
this.refs.text.value = '';
}
else{
alert("Fill author and text");
}
},
...
<form className="commentForm" onSubmit={this.formOnChange}>
<input type="text" placeholder="Your name" ref="author"/>
<input type="text" placeholder="Say something..." ref="text"/>
</form>
...
});
일반 HTML에서 처럼 onSubmit
이벤트를 사용할 수 있으므로 만든 함수를 binding한다.
form이 submit이 되면, input 태그에 붙어있는 ref
값을 이용해 DOM을 선택하고 값을 가져온다. 이 후 CommentBox
에서 만든 함수 dataChange
를 호출하기 위해 this.props.formHandler
함수를 호출한다.
함수가 호출되면 this.setState
함수에 의해 state에 변화가 일어나고 React에서는 그 변화를 감지하여 변화된 DOM만 re-rendering한다.
요약
React JS 라이브러리를 이용해 Web 개발을 해 보니 정말 편리하다는 느낌을 받았다. 위에 서술했던대로 Front를 전부 JS로 작성하니 코드를 난잡하지 않게 할 수 있었고, 상위 component에서 하위 component 방향으로 prop와 state를 이용한 data-flow 방식도 정말 재밌었다. 특히 state를 변경함으로써 해당 state 값을 사용하는 component만 re-rendering 하는 방식이 마음에 든다.
또한 이 글에 나오진 않지만 Mount라는 개념과 componentDidMount
, ComponentWillMount
등과 같은 Lifecycle Method도 흥미롭다.
'Programming' 카테고리의 다른 글
Nginx, PHP-FPM에서 child process 개수 결정하기 (0) | 2016.08.11 |
---|---|
React JS Lifecycle Method 소개 (0) | 2015.11.22 |
[Python] Web Driver & Selenium 사용하기 (7) | 2015.07.29 |
집단지성 프로그래밍 4(Hierarchical Clustering) (0) | 2015.07.12 |
집단지성 프로그래밍 3(Term Vector) (0) | 2015.07.08 |