SlideShare a Scribd company logo
김태곤
ReactJS로 시작하는
멀티 플랫폼 개발하기
오늘 소개할 내용
• ReactJS
• Server-side rendering
• React Native
• Desktop Web App
• React Native Desktop
ReactJS
Chapter 1
, 0
페이스북, 인스타그램같은
크고 복잡한 애플리케이션 제작을 위한
라이브러리 필요
MVC는 어쩌고?
MVC는
적합하지 않음
복잡한 UI에
끊임없이 변하는
M, V ,C가 상호 의존적인 구조
과도하게 연결된 컨트롤러
어디서 변할 지 모르는 모델
어쩌냥..
아!
재사용 가능한
UI 컴포넌트를 만드는
뷰 전용 라이브러리를
개발하면 되겠고냥
※ 실제로 고양이가 만든 건 아닙니다
a 4
멋진 웹 사이트를
만든다고

생각해봅시다
멋진 웹 사이트를
만든다고

생각해봅시다
여러 개
필요한 부품을
웹 사이트마다
새로 만든다면?
그래서 부품을

미리 정의하고

조립해서

결과물을 만듭니다.
웹은 이미
많은 컴포넌트의
조합입니다.
웹은 이미
많은 컴포넌트의
조합입니다.
CSS
HTML
JS
웹은 이
많은 컴
조합입
HTML
일단 여기에 집중해 봅시다
jQuery UI 탭 패널을 위해 필요한 HTML 코드
<div id="tabs">
<ul>
<li><a href="#fragment-1">One</a></li>
<li><a href="#fragment-2">Two</a></li>
<li><a href="#fragment-3">Three</a></li>
</ul>
<div id="fragment-1">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh
euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
</div>
<div id="fragment-2">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh
euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
</div>
<div id="fragment-3">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh
euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
</div>
</div>
웹은 이
많은 컴
조합입
HTML
태그는 충분한가요?
웹은 이
많은 컴
조합입
HTMLjQuery UI 탭 패널을 만들 때 필요한 HTML 코드
<div id="tabs">
<ul>
<li><a href="#fragment-1">One</a></li>
<li><a href="#fragment-2">Two</a></li>
<li><a href="#fragment-3">Three</a></li>
</ul>
<div id="fragment-1">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh
euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
</div>
<div id="fragment-2">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh
euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
</div>
<div id="fragment-3">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh
euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
</div>
</div>
웹은 이
많은 컴
조합입
HTML
<div id="tabs">
<ul>
<li><a href="#fragment-1">One</a></li>
<li><a href="#fragment-2">Two</a></li>
<li><a href="#fragment-3">Three</a></li>
</ul>
<div id="fragment-1">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh
euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
</div>
<div id="fragment-2">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh
euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
</div>
<div id="fragment-3">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh
euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
</div>
</div>
<li><
ListItem이지만 사실은 탭
<div
Division이지만 사실은 탭 패널
의미가 맞지 않는 태그를 컴포넌트로 사용심지어 기능을 정의/사용하는 코드(JS)는 별도 파일에 작성
웹은 이
많은 컴
조합입
HTML
<div id="tabs">
<ul>
<li><a href="#fragment-1">One</a></li>
<li><a href="#fragment-2">Two</a></li>
<li><a href="#fragment-3">Three</a></li>
</ul>
<div id="fragment-1">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh
euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
</div>
<div id="fragment-2">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh
euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
</div>
<div id="fragment-3">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh
euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
</div>
</div>
<li><
ListItem이지만 사실은 탭
<div
Division이지만 사실은 탭 패널
의미가 맞지 않는 태그를 컴포넌트로 사용
심지어 기능을 정의/사용하는 코드(JS)는 별도 파일에 작성
웹은 이
많은 컴
조합입
HTML
<div id="tabs">
<ul>
<li><a href="#fragment-1">One</a></li>
<li><a href="#fragment-2">Two</a></li>
<li><a href="#fragment-3">Three</a></li>
</ul>
<div id="fragment-1">
Lorem ipsum dolor sit amet, consectetuer adipiscing
elit, sed diam nonummy nibh euismod tincidunt ut
laoreet dolore magna aliquam erat volutpat.
</div>
<div id="fragment-2">
Lorem ipsum dolor sit amet, consectetuer adipiscing
elit, sed diam nonummy nibh euismod tincidunt ut
laoreet dolore magna aliquam erat volutpat.
</div>
<div id="fragment-3">
Lorem ipsum dolor sit amet, consectetuer adipiscing
elit, sed diam nonummy nibh euismod tincidunt ut
laoreet dolore magna aliquam erat volutpat.
</div>
</div>
<script>
jQuery(function($) {
$( "#tabs" ).tabs({
active: 1
});
});
</script>
의미가 더 명확한 쪽은?
<Tabs selectedIndex={1}>
<TabList>
<Tab>One</Tab>
<Tab>Two</Tab>
<Tab>Three</Tab>
</TabList>
<TabPanel>
Lorem ipsum dolor sit amet, consectetuer adipiscing
elit, sed diam nonummy nibh euismod tincidunt ut
laoreet dolore magna aliquam erat volutpat.
</TabPanel>
<TabPanel>
Lorem ipsum dolor sit amet, consectetuer adipiscing
elit, sed diam nonummy nibh euismod tincidunt ut
laoreet dolore magna aliquam erat volutpat.
</TabPanel>
<TabPanel>
Lorem ipsum dolor sit amet, consectetuer adipiscing
elit, sed diam nonummy nibh euismod tincidunt ut
laoreet dolore magna aliquam erat volutpat.
</TabPanel>
</Tabs>
, 0
가상 DOM
JSX 문법
단방향 데이터 흐름
Virtual DOM
One-way data flow
가상 DOM JSX 문법 단방향 데이터 흐름
- 스토얀 스테파노프, Yahoo YSlow 아키텍트
“자바스크립트에서 DOM 접근은 가능한 최소화하라”
가상 DOM JSX 문법 단방향 데이터 흐름
• 메모리에 가상의 DOM 트리를 구축
가상 DOM JSX 문법 단방향 데이터 흐름
• 값이 변경될 때마다 새로 렌더링 후 이전 트리와 비교
• 메모리에 가상의 DOM 트리를 구축
Before After
가상 DOM JSX 문법 단방향 데이터 흐름
• 값이 변경될 때마다 새로 렌더링 후 이전 트리와 비교
• 메모리에 가상의 DOM 트리를 구축
• 비교 후 실제 변경 사항이 있을 때 변경된 부분만 DOM에 반영
Before After
가상 DOM JSX 문법 단방향 데이터 흐름
• 값이 변경될 때마다 새로 렌더링 후 이전 트리와 비교
• 메모리에 가상의 DOM 트리를 구축
• 비교 후 실제 변경 사항이 있을 때 변경된 부분만 DOM에 반영
• 임의의 두 트리를 비교하는 최소 횟수는 O(n^3),

React에서는 같은 레벨의 트리만 비교하여 O(n)으로 최적화
Before After
가상 DOM JSX 문법 단방향 데이터 흐름
• 값이 변경될 때마다 새로 렌더링 후 이전 트리와 비교
• 메모리에 가상의 DOM 트리를 구축
• 비교 후 실제 변경 사항이 있을 때 변경된 부분만 DOM에 반영
• 임의의 두 트리를 비교하는 최소 횟수는 O(n^3),

React에서는 같은 레벨의 트리만 비교하여 O(n)으로 최적화
• 그 밖에도 목록 항목의 키 비교, 컴포넌트 비교, 배치 잡, 

자동 이벤트 위임, 선택적 하위 트리 렌더링 등을 통해

노력 대비 꽤 나은 성능 보장
Before After
가상 DOM JSX 문법 단방향 데이터 흐름
• 값이 변경될 때마다 새로 렌더링 후 이전 트리와 비교
• 메모리에 가상의 DOM 트리를 구축
• 비교 후 실제 변경 사항이 있을 때 변경된 부분만 DOM에 반영
• 임의의 두 트리를 비교하는 최소 횟수는 O(n^3),

React에서는 같은 레벨의 트리만 비교하여 O(n)으로 최적화
• 그 밖에도 목록 항목의 키 비교, 컴포넌트 비교, 배치 잡, 

자동 이벤트 위임, 선택적 하위 트리 렌더링 등을 통해

노력 대비 꽤 나은 성능 보장
React.js Conf 2015 - Hype! | http://youtu.be/z5e7kWSHWTg?t=4m10s
Angular ReactEmber
가상 DOM JSX 문법 단방향 데이터 흐름
• 값이 변경될 때마다 새로 렌더링 후 이전 트리와 비교
• 메모리에 가상의 DOM 트리를 구축
• 비교 후 실제 변경 사항이 있을 때 변경된 부분만 DOM에 반영
• 임의의 두 트리를 비교하는 최소 횟수는 O(n^3),

React에서는 같은 레벨의 트리만 비교하여 O(n)으로 최적화
• 그 밖에도 목록 항목의 키 비교, 컴포넌트 비교, 배치 잡, 

자동 이벤트 위임, 선택적 하위 트리 렌더링 등을 통해

노력 대비 꽤 나은 성능 보장
• Google은 2015년 7월에 Incremental DOM이라는 

Virtual DOM 라이브러리 발표
• Ember는 Glimmer라는 Virtual DOM 기술 적용
Virtual DOM != Silver Bullet
Angular 2 alpha 버전은 Virtual DOM 없이 더 나은 성능을 구현
그래도 꽤 나은 선택
http://goo.gl/k4pYbH
가상 DOM JSX 문법 단방향 데이터 흐름
• 값이 변경될 때마다 새로 렌더링 후 이전 트리와 비교
• 메모리에 가상의 DOM 트리를 구축
• 비교 후 실제 변경 사항이 있을 때 변경된 부분만 DOM에 반영
• 임의의 두 트리를 비교하는 최소 횟수는 O(n^3),

React에서는 같은 레벨의 트리만 비교하여 O(n)으로 최적화
• 그 밖에도 목록 항목의 키 비교, 컴포넌트 비교, 배치 잡, 

자동 이벤트 위임, 선택적 하위 트리 렌더링 등을 통해

노력 대비 꽤 나은 성능 보장
가상 DOM JSX 문법 단방향 데이터 흐름
• 자바스크립트 안에 XML을 표현하는 문법
var app = <Nav color="blur" />;
• 자바스크립트 코드로 변환해서 사용
var app = React.createElement(Nav, {color:"blue"});
• 속성 표현을 통해 문자열은 물론 자바스크립트 값을 그대로 전달
var app = <Nav color="blur" checked={true} name={name||"!"} />;
• 필수는 아니지만 거의 모든 React 프로젝트가 사용 중
가상 DOM JSX 문법 단방향 데이터 흐름
• 데이터는 상위 컴포넌트에서 하위 컴포넌트로만 흐름
• 상위에서 전달받은 값(props)은 수정 불가(immutable)
• 상위 컴포넌트는 하위 컴포넌트의 이벤트를 전달받아 업데이트
• 컴포넌트 내부의 상태는 스테이트(state)에 저장
• Flux: 애플리케이션 수준에서 적용한 단방향 데이터 흐름
c
var React = require('react');
var ReactDOM = require('react-dom');
var App = React.createClass({
render: function(){
return <h1>Hello, world!</h1>;
}
});
ReactDOM.render(
  <App list={[1, 2, 3]} />,
  document.getElementById('example')
);
var React = require('react');
var ReactDOM = require('react-dom');
var App = React.createClass({
render: function(){
return <h1>Hello, world!</h1>;
}
});
ReactDOM.render(
  <App list={[1, 2, 3]} />,
  document.getElementById('example')
);
require('react')
require('react-dom')
Node.js와 같은 CommonJS 방식 사용
var React = require('react');
var ReactDOM = require('react-dom');
var App = React.createClass({
render: function(){
return <h1>Hello, world!</h1>;
}
});
ReactDOM.render(
  <App list={[1, 2, 3]} />,
  document.getElementById('example')
);
<h1>Hello, world!</h1>
JS에 XML을 바로 쓰는 JSX 문법
var React = require('react');
var ReactDOM = require('react-dom');
var App = React.createClass({
render: function(){
return <h1>Hello, world!</h1>;
}
});
ReactDOM.render(
  <App list={[1, 2, 3]} />,
  document.getElementById('example')
);
<App list={[1, 2, 3]} />,
컴포넌트에 프로퍼티 전달(객체도 가능)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Hello React!</title>
<script src="build/react.js"></script>
<script src="build/react-dom.js"></script>
<script src="libs/babel-core/5.8.23/browser.min.js"></script>
</head>
<body>
<div id="example"></div>
<script type="text/babel">
var App = React.createClass({
render: function(){
return <h1>Hello, world!</h1>;
}
});
ReactDOM.render(
<App list={[1, 2, 3]} />,
document.getElementById('example')
);
</script>
</body>
</html>
브라우저에서 해석하게 할 수도 있지만…
번거롭고 불러오는 파일 많고 성능 안 좋고…
보통 프론트엔드 도구를 사용해 미리 변환
var React = require('react');
var ReactDOM = require('react-dom');
var App = React.createClass({
render: function(){
return <h1>Hello, world!</h1>;
}
});
ReactDOM.render(
  <App list={[1, 2, 3]} />,
  document.getElementById('example')
);
프론트엔드 도구를 사용하면
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
class App extends Component {
render() {
return <h1>Hello, world!</h1>;
}
}
ReactDOM.render(
  <App list={[1, 2, 3]} />,
  document.getElementById('example')
);
ES2015도 이렇게 쓸 수 있습니다
c
var React = require('react');
var ReactDOM = require('react-dom');
var Link = React.createClass({
render: function() {
return <a href={"/path/to/"+this.props.num}>Link</a>;
}
});
var App = React.createClass({
render: function(){
return (
<div>
<h1>Hello, world!</h1>
<Link num={this.props.list[1]} />
</div>
);
}
});
ReactDOM.render(
  <App list={[1, 2, 3]} />,
  document.getElementById('example')
);
var React = require('react');
var ReactDOM = require('react-dom');
var Link = React.createClass({
render: function() {
return <a href={"/path/to/"+this.props.num}>Link</a>;
}
});
var App = React.createClass({
render: function(){
return (
<div>
<h1>Hello, world!</h1>
<Link num={this.props.list[1]} />
</div>
);
}
});
ReactDOM.render(
  <App list={[1, 2, 3]} />,
  document.getElementById('example')
);
<App list={[1, 2, 3]} />
<Link num={this.props.list[1]} />
this.props.num
데이터는 위에서 아래로 흐른다.
ReactDOM.render(
  <App list={[1, 2, 3]} />,
  document.getElementById('example')
);
var React = require('react');
var ReactDOM = require('react-dom');
var Link = React.createClass({
render: function() {
return <a href={"/path/to/"+this.props.num}>Link</a>;
}.
});
var App = React.createClass({
render: function(){
return (
<div>
<h1>Hello, world!</h1>
<Link num={this.props.list[1]} />
</div>
);
}.
});
ReactDOM.render(
  <App list={[1, 2, 3]} />,
  document.getElementById('example')
var ReactDOM = require('react-dom');
var Link = React.createClass({
render: function() {
return <a href={"/path/to/"+this.props.num}>Link</a>;
}.
});
var App = React.createClass({
render: function(){
return (
<div>
<h1>Hello, world!</h1>
<Link num={this.props.list[1]} />
</div>
);
}.
});
var Link = React.createClass({
render: function() {
return <a href={"/path/to/"+this.props.num}>Link</a>;
}.
});
var App = React.createClass({var App = React.createClass({
handleClick: function(event) {
this.setState({clickedElement: event.target});
},
render: function(){
return (
<div>
<h1>Hello, world!</h1>
<Link num={this.props.list[1]} onClick={this.handleClick} />
</div>
);
}
});
var Link = React.createClass({
render: function() {
return <a href={"/path/to/"+this.props.num}
onClick={this.props.onClick}>Link</a>;
}.
});
var App = React.createClass({
handleClick: function(event) {
this.setState({clickedElement: event.target});
},
render: function(){
return (
<div>
<h1>Hello, world!</h1>
<Link num={this.props.list[1]} onClick={this.handleClick} />
</div>
);
}
});
var Link = React.createClass({
render: function() {
return <a href={"/path/to/"+this.props.num}
onClick={this.props.onClick}>Link</a>;
}.
});
var App = React.createClass({
handleClick: function(event) {
this.setState({clickedElement: event.target});
},
render: function(){
return (
<div>
<h1>Hello, world!</h1>
<Link num={this.props.list[1]} onClick={this.handleClick} />
</div>
);
}
});
onClick={this.props.onClick}
onClick={this.handleClick}
handleClick: function(event) {
this.setState({clickedElement: event.target});
},
이벤트를 통해 하위 컴포넌트가
상위 컴포넌트에 값을 전달할 수 있다
c4
?
이미 많은 서비스가 React 사용 중
심지어 페이스북은 알파 버전 사용 중!
참고자료
https://taegon.kim/archives/5288
Flux와 Redux
http://www.slideshare.net/jeokrang/facebook-react-55649927
Facebook은 React를 왜 만들었을까?
http://webframeworks.kr/tutorials/react/es2015-react/
ES2015와 React
http://webframeworks.kr/tutorials/react/getting-started/
React 시작하기
Server-side Rendering
Chapter 2
성능
페이지 로딩 + 자바스크립트 로딩 + 렌더링 =

초기 구동 속도가 느리다
검색 엔진 최적화
자바스크립트를 실행하지 못하는 크롤러는

페이지의 콘텐츠를 수집하지 못한다
클라이언트 렌더링의
성능

매번 전체 페이지를 다시 읽는 것보다 빠름
사용자 경험

자연스럽게 연결되는 사용자 경험 가능
코드의 일관성

렌더링 책임은 한 쪽에만 주는 편이 일관성 유지가 쉬움
장점 단점
성능

페이지 로딩 + JS 로딩 + 렌더링 (+ 데이터 로딩)=

초기 구동 속도가 느림
검색 엔진 최적화

자바스크립트를 실행하지 못하는 크롤러는

페이지의 콘텐츠를 수집하지 못함
단점클라이언트 렌더링의
둘 다!
그래서 해답은?
+ 서버 렌더링클라이언트 렌더링
빈 페이지 App
HTML 문서 전송 JS 전송 후 렌더링빈
콘텐츠를 볼 수 없음
클라이언트 렌더링
App
+ 서버 렌더링
JS 전송 후
DOM에 붙음
HTML 문서 전송
렌더링된
콘텐츠는 볼 수 있지만,
인터랙션은 아직 동작 안함
R
사용자가 느끼는
웹 사이트 반응 속도는
콘텐츠를 처음 본 시간에
영향을 받는다
c
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
class App extends Component {
render() {
return <h1>Hello, world!</h1>;
}
}
ReactDOM.render(
  <App list={[1, 2, 3]} />,
  document.getElementById('example')
);
앞서 살펴 본 클라이언트 코드
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
class App extends Component {
render() {
return <h1>Hello, world!</h1>;
}
}
ReactDOM.render(
  <App list={[1, 2, 3]} />,
  document.getElementById('example')
);
ReactDOM은 브라우저 환경에만 해당
import ReactDOM from 'react-dom';
ReactDOM.render
import ReactDOM from 'react-dom';
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
class App extends Component {
render() {
return <h1>Hello, world!</h1>;
}
}
ReactDOM.render(
  <App list={[1, 2, 3]} />,
  document.getElementById('example')
);
DOM 관련 부분만 별도 파일로 분리
import ReactDOM from 'react-dom';
ReactDOM.render
import React, { Component } from 'react';
ReactDOM.render(
  <App list={[1, 2, 3]} />,
  document.getElementById('example')
);
class App extends Component {
render() {
return <h1>Hello, world!</h1>;
}
}
import ReactDOM from 'react-dom';
DOM 관련 부분만 별도 파일로 분리
import React, { Component } from 'react';
ReactDOM.render(
  <App list={[1, 2, 3]} />,
  document.getElementById('example')
);
export default App;
import App from './App';
browser.js
App.js
class App extends Component {
render() {
return <h1>Hello, world!</h1>;
}
}
import ReactDOM from 'react-dom';
DOM 관련 부분만 별도 파일로 분리
import React, { Component } from 'react';
class App extends Component {
render() {
return <h1>Hello, world!</h1>;
}
}
ReactDOM.render(
  <App list={[1, 2, 3]} />,
  document.getElementById('example')
);
export default App;
import App from './App';
browser.js
App.js
import ReactServer from 'react-dom/server';
서버 렌더링은 react-dom/server 사용
import React, { Component } from 'react';
class App extends Component {
render() {
return <h1>Hello, world!</h1>;
}
}
var result = ReactServer.renderToString(
  <App list={[1, 2, 3]} />
);
export default App;
import App from './App';
server.js
App.js
import ReactServer from 'react-dom/server';
결과물을 HTML 페이지에 출력
<body>
<div id="example">
{{result}}
</div>
</body>
var result = ReactServer.renderToString(
  <App list={[1, 2, 3]} />
);
import App from './App';
server.js
index.html
import ReactServer from 'react-dom/server';
결과물을 HTML 페이지에 출력
<body>
<div id="example">
{{result}}
</div>
</body>
var result = ReactServer.renderToString(
  <App list={[1, 2, 3]} />
);
import App from './App';
server.js
index.html
{{result}}
result
렌더링된 결과물이 서버에서 전송된 예제
Isomorphic JavaScript
서버와 클라이언트가 같은 코드를 공유하는 개발 방식같은 코드를 공유
Client Server
공통
코드
Isomorphic JavaScript
서버와 클라이언트가 같은 코드를 공유하는 개발 방식
Client Server
React
같은 코드를 공유
참고자료
https://taegon.kim/archives/5312
React 애플리케이션의 서버 렌더링
http://isomorphic.net/
React를 비롯한 Isomorphic JavaScript 라이브러리를 소개하는 곳
http://augustl.com/blog/2014/jdk8_react_rendering_on_server/
JDK8(Clojure)에서 React 렌더링하는 법 (영문)
http://www.phpied.com/server-side-react-with-php/
PHP 서버에서 React 렌더링하는 법 (영문)
React Native
chapter 3
Virtual DOM DOM
Virtual DOM의 결과물은 DOM이 될 수도 있지만
Virtual DOM DOM
SVG
Canvas
"string"
문자열, SVG, Canvas 등으로 확장 가능
예제: React ART
...
renderGraphic: function(rotation) {
return (
<Group
onMouseDown={this.handleMouseDown}
onMouseUp={this.handleMouseUp}>
<Group x={210} y={135}>
<Shape fill="rgba(0,0,0,0.1)" d={BORDER_PATH} />
<Shape fill="#7BC7BA" d={BG_PATH} />
<Shape fill="#DCDCDC" d={BAR_PATH} />
<Shape fill="#D97B76" d={RED_DOT_PATH} />
<Shape fill="#DBBB79" d={YELLOW_DOT_PATH} />
<Shape fill="#A6BD8A" d={GREEN_DOT_PATH} />
<Group x={55} y={29}>
<Group rotation={rotation} originX={84} originY={89}>
<Shape fill="#FFFFFF" d={CENTER_DOT_PATH} />
<Group>
<Shape d={RING_ONE_PATH} stroke="#FFFFFF" strokeWidth={8} />
<Shape d={RING_TWO_PATH} transform={RING_TWO_ROTATE} stroke="#FFFFFF" strokeWidth={8} />
<Shape d={RING_THREE_PATH} transform={RING_THREE_ROTATE} stroke="#FFFFFF" strokeWidth={8} />
</Group>
</Group>
</Group>
</Group>
</Group>
);
}
...
예제: React ART
Virtual DOM DOM
SVG
Canvas
"string"
문자열, SVG, Canvas 등으로 확장 가능
Virtual DOM
Native Component
네이티브 컴포넌트로 확장할 수도 있음
H 4
네이티브 컴포넌트
비동기 실행
Flexbox 레이아웃
폴리필(Polyfill)
간편한 네이티브 확장
네이티브 컴포넌트
비동기 실행
Flexbox 레이아웃
폴리필(Polyfill)
간편한 네이티브 확장
<header> <footer>,
<section> <div> <span>
<img> <a> <strong>
<em> <form> <select>
<input> <textarea>
<button> ...
<View> <Text> <Image>
<ScrollView> <ListView>
<WebView> <PickerIOS>
<NavigatorIOS>
<ActivityIndicatorIOS>
<ProgressViewIOS>
<SwitchIOS>...
<View> <Text> <Image>
<ScrollView> <ListView>
<WebView>
<DrawerLayoutAndroid>
<ProgressBarAndroid>
<SwitchAndroid>
<ViewPagerAndroid> ...
네이티브 컴포넌트
비동기 실행
Flexbox 레이아웃
폴리필(Polyfill)
간편한 네이티브 확장
• 자바스크립트는 네이티브보다 훨씬 느리기 때문에 동기 실행시
네이티브 UI와 자바스크립트 간의 병목 현상 발생
• 네이티브와 자바스크립트 사이에 메시지 큐를 두어 비동기 실행
JS VM Native
Java/C++/ObjC/Switft
비동기 실행
Flexbox 레이아웃
폴리필(Polyfill)
간편한 네이티브 확장
• CSS와 구조가 비슷한 StyleSheet 객체 사용
• CSS3 Flexbox와 비슷한 방식으로 레이아웃 스타일링
var ReactNative = React.createClass({
render: function() {
return (
<View style={styles.row}>
<View style={styles.text}>
<Text style={styles.title}>React Native</Text>
<Text style={styles.subtitle}>Build mobile apps using React</Text>
</View>
</View>
);
},
});
var styles = StyleSheet.create({
row: { flexDirection: 'row', margin: 40 },
text: { flex: 1, justifyContent: 'center'},
title: { fontSize: 11, fontWeight: 'bold' },
subtitle: { fontSize: 10 },
});
xbox 레이아웃
폴리필(Polyfill)
간편한 네이티브 확장
• XHR, requestAnimationFrame, navigator.geolocation 등
익숙한 자바스크립트 기능 제공
var GeoInfo = React.createClass({
getInitialState: function() {
return { position: 'unknown' };
},
componentDidMount: function() {
navigator.geolocation.getCurrentPosition(
(position) => this.setState({position}),
(error) => console.error(error)
);
},
render: function() {
return (
<Text>
Position: {JSON.stringify(this.state.position)}
</Text>
);
},
});
리필(Polyfill)
간편한 네이티브 확장
• Java(Android), ObjectiveC/Swift (iOS)로 작성된

네이티브 모듈을 손쉽게 자바스크립트 모듈로 바인딩
// Java
public class MyCustomModule extends ReactContextBaseJavaModule {
// Available as NativeModules.MyCustomModule.processString
@ReactMethod
public void processString(String input, Callback callback) {
callback.invoke(input.replace("Goodbye", "Hello"));
}
}
// JavaScript
...
componentDidMount() {
NativeModules.MyCustomModule.processString(this.state.text, (text) => {
this.setState({text});
});
},
...
, . 1.
$ brew install node watchman
$ node install -g react-native-cli
필요한 패키지 설치 (Xcode 및 안드로이드 SDK 필수)
프로젝트 생성
$ react-native init HelloWorld
프로젝트 오픈 후 컴파일
$ cd HellWorld
$ open ios/HelloWorld.xcodeproj (iOS)
$ react-native run-android (Android)
코드는 index.{ios, android}.js 파일 수정
React Playground
데모
• 기본 네이티브 컴포넌트만 사용
• React에 익숙하지 않은 상태에서

대략 20시간 소요
• 네이티브와 똑같은 무한 스크롤 성능
https://www.youtube.com/watch?v=fRaC9jECxCg
페이스북의 AdManager 개발 사례
• iOS 개발 후 안드로이드 버전 개발
• 각 플랫폼에 맞는 네이티브 룩앤필
• 전체 코드의 85% 가량을 재사용
• 두 플랫폼의 저장소 통합 관리
안 배워도 되겠네요?
이제 네이티브를
ReactJS로 시작하는 멀티플랫폼 개발하기
JS 모르고 jQuery만 알면 되던가요?
결국 네이티브라는 장애물을 넘어야 합니다.
물론 남이 삽질해주길 기다리는 방법도 있죠
삽질의 결과물은 react.parts에서...
참고자료
https://realm.io/kr/news/react-native/
리액트 네이티브로 시작하는 앱 개발 #1
http://react.parts/
React 네이티브 컴포넌트
https://rnplay.org/
React Native Playground
Desktop WebApp
Chapter 4
이미 거의 끝났습니다.
웹 앱이 완성됐다면 데스크톱 앱은
약간의 양념만 있으면 되쥬. 솨아~
ReactJS로 시작하는 멀티플랫폼 개발하기
은..
크로미움 엔진과 Node.js가 합쳐진 데스크톱 애플리케이션 런타임
은..
코드 하나로 맥, 리눅스, 윈도우 플랫폼과 32/64비트 모두 지원
</>
이미 많은 기업에서 사용 중
은..
최근 워드프레스는 Calypso라는 프로젝트를 통해
wordpress.com의 프론트엔드를 모두 대체
React + Node.js 서버를 사용한 Isomorphic JavaScript
동일한 코드를 Desktop App에도 사용
React 앱 패키징
$ npm install -g electron-packager

$ cd HelloWorld
$ electron-packager . HelloWorldApp --platform=all --arch=x64 --version=0.35.4
HelloWorld
├─ package.json
└┬ src
├─ index.html
├─ main.js
├─ other.js
└─ style.css
폴더 구조를 왼쪽과 같이 작성한 후...
단, OS X / Linux에서 Windows 앱을 빌드하려면 wine 필요wine
참고 자료
https://github.com/chentsulin/electron-react-boilerplate
Electron과 React를 사용한 데스크톱 앱 프로젝트 시작 틀
https://github.com/sindresorhus/awesome-electron
Electron 관련 정보를 모아 둔 페이지
https://github.com/gabrielbull/react-desktop
데스크톱 환경에 사용할 수 있는 React UI 컴포넌트 모음
React Native Desktop
Chapter 5
그래도 네이티브가 더 좋다면?
image from 이말년씨리즈
데스크톱 웹 앱 좋은 거 알겠는데
데스크톱 네이티브? 원한다면 주도록 하지
잘 찾아봐. GitHub에 두고 왔으니…
image from 원피스
React Native를
포크한 프로젝트라
사용법도 비슷합니다
예제 실행방법
$ git clone https://github.com/ptmt/react-native-desktop

$ cd react-native-desktop && npm install
Examples 아래의 원하는 폴더로 가서 .xcodeproj 파일을 XCode에서 열고 컴파일
Hello World 앱 크기 비교
React Native Desktop
3.5MB
105.3MB
(OS X 빌드 기준)
하지만
image from 수퍼마리오
윈도우 버전도 없고 (OSX만 지원)
image from 수퍼마리오
기능도 적고 불안정합니다
image from 수퍼마리오
실무에는 절대로 사용하지 마세요!
개발 초기라 매우 불안정하니
Once,Write Run Anywhere
Once, WriteLearn Anywhere
한 번 배워 어디서나 개발하자
https://taegon.kim
@taggon
Thank You!
facebook.com/groups/react.ko
...and
Credits
Twitter and Wordpress icons are made by Freepik from www.flaticon.com
All images without any notes are published under Creative Commons zero.
All videos are published under Creative Commons zero.

More Related Content

What's hot

AWSでDockerを扱うためのベストプラクティス
AWSでDockerを扱うためのベストプラクティスAWSでDockerを扱うためのベストプラクティス
AWSでDockerを扱うためのベストプラクティス
Amazon Web Services Japan
 
AWS Summit Seoul 2023 | 모두를 위한 BI, QuickSight
AWS Summit Seoul 2023 | 모두를 위한 BI, QuickSightAWS Summit Seoul 2023 | 모두를 위한 BI, QuickSight
AWS Summit Seoul 2023 | 모두를 위한 BI, QuickSight
Amazon Web Services Korea
 
AWS로 사용자 천만 명 서비스 만들기 (윤석찬)- 클라우드 태권 2015
AWS로 사용자 천만 명 서비스 만들기 (윤석찬)- 클라우드 태권 2015 AWS로 사용자 천만 명 서비스 만들기 (윤석찬)- 클라우드 태권 2015
AWS로 사용자 천만 명 서비스 만들기 (윤석찬)- 클라우드 태권 2015
Amazon Web Services Korea
 
AWS 클라우드 기반 확장성 높은 천만 사용자 웹 서비스 만들기 - 윤석찬
AWS 클라우드 기반 확장성 높은 천만 사용자 웹 서비스 만들기 - 윤석찬AWS 클라우드 기반 확장성 높은 천만 사용자 웹 서비스 만들기 - 윤석찬
AWS 클라우드 기반 확장성 높은 천만 사용자 웹 서비스 만들기 - 윤석찬
Amazon Web Services Korea
 
AWS Black Belt Techシリーズ Amazon CloudSearch
AWS Black Belt Techシリーズ Amazon CloudSearchAWS Black Belt Techシリーズ Amazon CloudSearch
AWS Black Belt Techシリーズ Amazon CloudSearch
Amazon Web Services Japan
 
[NDC17] Kubernetes로 개발서버 간단히 찍어내기
[NDC17] Kubernetes로 개발서버 간단히 찍어내기[NDC17] Kubernetes로 개발서버 간단히 찍어내기
[NDC17] Kubernetes로 개발서버 간단히 찍어내기
SeungYong Oh
 
클라우드 여정의 시작 - 클라우드 전문가 조직의 프랙티컬 가이드-김학민, AWS SA Manager::AWS 마이그레이션 A to Z 웨비나
클라우드 여정의 시작 - 클라우드 전문가 조직의 프랙티컬 가이드-김학민, AWS SA Manager::AWS 마이그레이션 A to Z 웨비나클라우드 여정의 시작 - 클라우드 전문가 조직의 프랙티컬 가이드-김학민, AWS SA Manager::AWS 마이그레이션 A to Z 웨비나
클라우드 여정의 시작 - 클라우드 전문가 조직의 프랙티컬 가이드-김학민, AWS SA Manager::AWS 마이그레이션 A to Z 웨비나
Amazon Web Services Korea
 
[20210519 Security-JAWS] AWS エッジサービス入門ハンズオンの紹介と AWS WAF のアップデートについて
[20210519 Security-JAWS] AWS エッジサービス入門ハンズオンの紹介と AWS WAF のアップデートについて[20210519 Security-JAWS] AWS エッジサービス入門ハンズオンの紹介と AWS WAF のアップデートについて
[20210519 Security-JAWS] AWS エッジサービス入門ハンズオンの紹介と AWS WAF のアップデートについて
Amazon Web Services Japan
 
私がなぜZscalerに?
私がなぜZscalerに?私がなぜZscalerに?
私がなぜZscalerに?
Takayoshi Takaoka
 
Site Reliability Engineering (SRE)を可能にするOpenPIEのご紹介
Site Reliability Engineering (SRE)を可能にするOpenPIEのご紹介Site Reliability Engineering (SRE)を可能にするOpenPIEのご紹介
Site Reliability Engineering (SRE)を可能にするOpenPIEのご紹介
OSSラボ株式会社
 
Security on AWS :: 이경수 솔루션즈아키텍트
Security on AWS :: 이경수 솔루션즈아키텍트Security on AWS :: 이경수 솔루션즈아키텍트
Security on AWS :: 이경수 솔루션즈아키텍트
Amazon Web Services Korea
 
CDN and WAF
CDN and WAFCDN and WAF
CDN and WAF
Shigeru Yokochi
 
높은 가용성과 성능 향상을 위한 ElastiCache 활용 팁 - 임근택, SendBird :: AWS Summit Seoul 2019
높은 가용성과 성능 향상을 위한 ElastiCache 활용 팁 - 임근택, SendBird :: AWS Summit Seoul 2019 높은 가용성과 성능 향상을 위한 ElastiCache 활용 팁 - 임근택, SendBird :: AWS Summit Seoul 2019
높은 가용성과 성능 향상을 위한 ElastiCache 활용 팁 - 임근택, SendBird :: AWS Summit Seoul 2019
Amazon Web Services Korea
 
Amazon EKS로 간단한 웹 애플리케이션 구축하기 - 김주영 (AWS) :: AWS Community Day Online 2021
Amazon EKS로 간단한 웹 애플리케이션 구축하기 - 김주영 (AWS) :: AWS Community Day Online 2021Amazon EKS로 간단한 웹 애플리케이션 구축하기 - 김주영 (AWS) :: AWS Community Day Online 2021
Amazon EKS로 간단한 웹 애플리케이션 구축하기 - 김주영 (AWS) :: AWS Community Day Online 2021
AWSKRUG - AWS한국사용자모임
 
20200804 AWS Black Belt Online Seminar Amazon CodeGuru
20200804 AWS Black Belt Online Seminar Amazon CodeGuru20200804 AWS Black Belt Online Seminar Amazon CodeGuru
20200804 AWS Black Belt Online Seminar Amazon CodeGuru
Amazon Web Services Japan
 
DatadogでAWS監視やってみた
DatadogでAWS監視やってみたDatadogでAWS監視やってみた
DatadogでAWS監視やってみた
tyamane
 
分散トレーシング技術について(Open tracingやjaeger)
分散トレーシング技術について(Open tracingやjaeger)分散トレーシング技術について(Open tracingやjaeger)
分散トレーシング技術について(Open tracingやjaeger)
NTT Communications Technology Development
 
AWS Transit Gateway를 통한 Multi-VPC 아키텍처 패턴 - 강동환 솔루션즈 아키텍트, AWS :: AWS Summit ...
AWS Transit Gateway를 통한 Multi-VPC 아키텍처 패턴 - 강동환 솔루션즈 아키텍트, AWS :: AWS Summit ...AWS Transit Gateway를 통한 Multi-VPC 아키텍처 패턴 - 강동환 솔루션즈 아키텍트, AWS :: AWS Summit ...
AWS Transit Gateway를 통한 Multi-VPC 아키텍처 패턴 - 강동환 솔루션즈 아키텍트, AWS :: AWS Summit ...
Amazon Web Services Korea
 
AWS Summit Seoul 2023 |투자를 모두에게, 토스증권의 MTS 구축 사례
AWS Summit Seoul 2023 |투자를 모두에게, 토스증권의 MTS 구축 사례AWS Summit Seoul 2023 |투자를 모두에게, 토스증권의 MTS 구축 사례
AWS Summit Seoul 2023 |투자를 모두에게, 토스증권의 MTS 구축 사례
Amazon Web Services Korea
 
Google Cloud Game Servers 徹底入門 | 第 10 回 Google Cloud INSIDE Games & Apps Online
Google Cloud Game Servers 徹底入門 | 第 10 回 Google Cloud INSIDE Games & Apps OnlineGoogle Cloud Game Servers 徹底入門 | 第 10 回 Google Cloud INSIDE Games & Apps Online
Google Cloud Game Servers 徹底入門 | 第 10 回 Google Cloud INSIDE Games & Apps Online
Google Cloud Platform - Japan
 

What's hot (20)

AWSでDockerを扱うためのベストプラクティス
AWSでDockerを扱うためのベストプラクティスAWSでDockerを扱うためのベストプラクティス
AWSでDockerを扱うためのベストプラクティス
 
AWS Summit Seoul 2023 | 모두를 위한 BI, QuickSight
AWS Summit Seoul 2023 | 모두를 위한 BI, QuickSightAWS Summit Seoul 2023 | 모두를 위한 BI, QuickSight
AWS Summit Seoul 2023 | 모두를 위한 BI, QuickSight
 
AWS로 사용자 천만 명 서비스 만들기 (윤석찬)- 클라우드 태권 2015
AWS로 사용자 천만 명 서비스 만들기 (윤석찬)- 클라우드 태권 2015 AWS로 사용자 천만 명 서비스 만들기 (윤석찬)- 클라우드 태권 2015
AWS로 사용자 천만 명 서비스 만들기 (윤석찬)- 클라우드 태권 2015
 
AWS 클라우드 기반 확장성 높은 천만 사용자 웹 서비스 만들기 - 윤석찬
AWS 클라우드 기반 확장성 높은 천만 사용자 웹 서비스 만들기 - 윤석찬AWS 클라우드 기반 확장성 높은 천만 사용자 웹 서비스 만들기 - 윤석찬
AWS 클라우드 기반 확장성 높은 천만 사용자 웹 서비스 만들기 - 윤석찬
 
AWS Black Belt Techシリーズ Amazon CloudSearch
AWS Black Belt Techシリーズ Amazon CloudSearchAWS Black Belt Techシリーズ Amazon CloudSearch
AWS Black Belt Techシリーズ Amazon CloudSearch
 
[NDC17] Kubernetes로 개발서버 간단히 찍어내기
[NDC17] Kubernetes로 개발서버 간단히 찍어내기[NDC17] Kubernetes로 개발서버 간단히 찍어내기
[NDC17] Kubernetes로 개발서버 간단히 찍어내기
 
클라우드 여정의 시작 - 클라우드 전문가 조직의 프랙티컬 가이드-김학민, AWS SA Manager::AWS 마이그레이션 A to Z 웨비나
클라우드 여정의 시작 - 클라우드 전문가 조직의 프랙티컬 가이드-김학민, AWS SA Manager::AWS 마이그레이션 A to Z 웨비나클라우드 여정의 시작 - 클라우드 전문가 조직의 프랙티컬 가이드-김학민, AWS SA Manager::AWS 마이그레이션 A to Z 웨비나
클라우드 여정의 시작 - 클라우드 전문가 조직의 프랙티컬 가이드-김학민, AWS SA Manager::AWS 마이그레이션 A to Z 웨비나
 
[20210519 Security-JAWS] AWS エッジサービス入門ハンズオンの紹介と AWS WAF のアップデートについて
[20210519 Security-JAWS] AWS エッジサービス入門ハンズオンの紹介と AWS WAF のアップデートについて[20210519 Security-JAWS] AWS エッジサービス入門ハンズオンの紹介と AWS WAF のアップデートについて
[20210519 Security-JAWS] AWS エッジサービス入門ハンズオンの紹介と AWS WAF のアップデートについて
 
私がなぜZscalerに?
私がなぜZscalerに?私がなぜZscalerに?
私がなぜZscalerに?
 
Site Reliability Engineering (SRE)を可能にするOpenPIEのご紹介
Site Reliability Engineering (SRE)を可能にするOpenPIEのご紹介Site Reliability Engineering (SRE)を可能にするOpenPIEのご紹介
Site Reliability Engineering (SRE)を可能にするOpenPIEのご紹介
 
Security on AWS :: 이경수 솔루션즈아키텍트
Security on AWS :: 이경수 솔루션즈아키텍트Security on AWS :: 이경수 솔루션즈아키텍트
Security on AWS :: 이경수 솔루션즈아키텍트
 
CDN and WAF
CDN and WAFCDN and WAF
CDN and WAF
 
높은 가용성과 성능 향상을 위한 ElastiCache 활용 팁 - 임근택, SendBird :: AWS Summit Seoul 2019
높은 가용성과 성능 향상을 위한 ElastiCache 활용 팁 - 임근택, SendBird :: AWS Summit Seoul 2019 높은 가용성과 성능 향상을 위한 ElastiCache 활용 팁 - 임근택, SendBird :: AWS Summit Seoul 2019
높은 가용성과 성능 향상을 위한 ElastiCache 활용 팁 - 임근택, SendBird :: AWS Summit Seoul 2019
 
Amazon EKS로 간단한 웹 애플리케이션 구축하기 - 김주영 (AWS) :: AWS Community Day Online 2021
Amazon EKS로 간단한 웹 애플리케이션 구축하기 - 김주영 (AWS) :: AWS Community Day Online 2021Amazon EKS로 간단한 웹 애플리케이션 구축하기 - 김주영 (AWS) :: AWS Community Day Online 2021
Amazon EKS로 간단한 웹 애플리케이션 구축하기 - 김주영 (AWS) :: AWS Community Day Online 2021
 
20200804 AWS Black Belt Online Seminar Amazon CodeGuru
20200804 AWS Black Belt Online Seminar Amazon CodeGuru20200804 AWS Black Belt Online Seminar Amazon CodeGuru
20200804 AWS Black Belt Online Seminar Amazon CodeGuru
 
DatadogでAWS監視やってみた
DatadogでAWS監視やってみたDatadogでAWS監視やってみた
DatadogでAWS監視やってみた
 
分散トレーシング技術について(Open tracingやjaeger)
分散トレーシング技術について(Open tracingやjaeger)分散トレーシング技術について(Open tracingやjaeger)
分散トレーシング技術について(Open tracingやjaeger)
 
AWS Transit Gateway를 통한 Multi-VPC 아키텍처 패턴 - 강동환 솔루션즈 아키텍트, AWS :: AWS Summit ...
AWS Transit Gateway를 통한 Multi-VPC 아키텍처 패턴 - 강동환 솔루션즈 아키텍트, AWS :: AWS Summit ...AWS Transit Gateway를 통한 Multi-VPC 아키텍처 패턴 - 강동환 솔루션즈 아키텍트, AWS :: AWS Summit ...
AWS Transit Gateway를 통한 Multi-VPC 아키텍처 패턴 - 강동환 솔루션즈 아키텍트, AWS :: AWS Summit ...
 
AWS Summit Seoul 2023 |투자를 모두에게, 토스증권의 MTS 구축 사례
AWS Summit Seoul 2023 |투자를 모두에게, 토스증권의 MTS 구축 사례AWS Summit Seoul 2023 |투자를 모두에게, 토스증권의 MTS 구축 사례
AWS Summit Seoul 2023 |투자를 모두에게, 토스증권의 MTS 구축 사례
 
Google Cloud Game Servers 徹底入門 | 第 10 回 Google Cloud INSIDE Games & Apps Online
Google Cloud Game Servers 徹底入門 | 第 10 回 Google Cloud INSIDE Games & Apps OnlineGoogle Cloud Game Servers 徹底入門 | 第 10 回 Google Cloud INSIDE Games & Apps Online
Google Cloud Game Servers 徹底入門 | 第 10 回 Google Cloud INSIDE Games & Apps Online
 

Similar to ReactJS로 시작하는 멀티플랫폼 개발하기

XECon2015 :: [2-2] 박상현 - React로 개발하는 SPA 실무 이야기
XECon2015 :: [2-2] 박상현 - React로 개발하는 SPA 실무 이야기XECon2015 :: [2-2] 박상현 - React로 개발하는 SPA 실무 이야기
XECon2015 :: [2-2] 박상현 - React로 개발하는 SPA 실무 이야기
XpressEngine
 
Front end dev 2016 & beyond
Front end dev 2016 & beyondFront end dev 2016 & beyond
Front end dev 2016 & beyond
Jae Sung Park
 
[114]angularvs react 김훈민손찬욱
[114]angularvs react 김훈민손찬욱[114]angularvs react 김훈민손찬욱
[114]angularvs react 김훈민손찬욱
NAVER D2
 
Javascript 생태계
Javascript 생태계Javascript 생태계
Javascript 생태계
Herren
 
4-3. jquery
4-3. jquery4-3. jquery
4-3. jquery
JinKyoungHeo
 
React 튜토리얼 1차시
React 튜토리얼 1차시React 튜토리얼 1차시
React 튜토리얼 1차시
태현 김
 
코드잇-리액트-특강.pdf
코드잇-리액트-특강.pdf코드잇-리액트-특강.pdf
코드잇-리액트-특강.pdf
이정환
 
웹 프론트엔드 테스팅
웹 프론트엔드 테스팅웹 프론트엔드 테스팅
웹 프론트엔드 테스팅
Eunsu Kim
 
[Codelab 2017] ReactJS 기초
[Codelab 2017] ReactJS 기초[Codelab 2017] ReactJS 기초
[Codelab 2017] ReactJS 기초
양재동 코드랩
 
웹 브라우저는 어떻게 동작하나? (2)
웹 브라우저는 어떻게 동작하나? (2)웹 브라우저는 어떻게 동작하나? (2)
웹 브라우저는 어떻게 동작하나? (2)
Joone Hur
 
[Korea Linux Forum] Implementing web based online multiplayer tetris with Ope...
[Korea Linux Forum] Implementing web based online multiplayer tetris with Ope...[Korea Linux Forum] Implementing web based online multiplayer tetris with Ope...
[Korea Linux Forum] Implementing web based online multiplayer tetris with Ope...
JinKwon Lee
 
Meteor 0.3.6 Preview
Meteor 0.3.6 PreviewMeteor 0.3.6 Preview
Meteor 0.3.6 Preview
Juntai Park
 
20150912 windows 10 앱 tips tricks
20150912 windows 10 앱 tips  tricks20150912 windows 10 앱 tips  tricks
20150912 windows 10 앱 tips tricks
영욱 김
 
[아꿈사/111105] html5 9장 클라이언트측 데이터로 작업하기
[아꿈사/111105] html5 9장 클라이언트측 데이터로 작업하기[아꿈사/111105] html5 9장 클라이언트측 데이터로 작업하기
[아꿈사/111105] html5 9장 클라이언트측 데이터로 작업하기
sung ki choi
 
JQuery를 이용하여 웹 위젯 작성하기_(주)시스포유아이앤씨
JQuery를 이용하여 웹 위젯 작성하기_(주)시스포유아이앤씨JQuery를 이용하여 웹 위젯 작성하기_(주)시스포유아이앤씨
JQuery를 이용하여 웹 위젯 작성하기_(주)시스포유아이앤씨
sys4u
 
Hacosa jquery 1th
Hacosa jquery 1thHacosa jquery 1th
Hacosa jquery 1th
Seong Bong Ji
 
Java script 강의자료_ed13
Java script 강의자료_ed13Java script 강의자료_ed13
Java script 강의자료_ed13
hungrok
 
자바 웹 개발 시작하기 (5주차 : 스프링 프래임워크)
자바 웹 개발 시작하기 (5주차 : 스프링 프래임워크)자바 웹 개발 시작하기 (5주차 : 스프링 프래임워크)
자바 웹 개발 시작하기 (5주차 : 스프링 프래임워크)
DK Lee
 
Social Tutorial Platform: Webbles
Social Tutorial Platform: Webbles Social Tutorial Platform: Webbles
Social Tutorial Platform: Webbles
Wonkyung Lyu
 
프로그래밍 패러다임의 진화 및 Spring의 금융권 적용
프로그래밍 패러다임의 진화 및 Spring의 금융권 적용프로그래밍 패러다임의 진화 및 Spring의 금융권 적용
프로그래밍 패러다임의 진화 및 Spring의 금융권 적용
중선 곽
 

Similar to ReactJS로 시작하는 멀티플랫폼 개발하기 (20)

XECon2015 :: [2-2] 박상현 - React로 개발하는 SPA 실무 이야기
XECon2015 :: [2-2] 박상현 - React로 개발하는 SPA 실무 이야기XECon2015 :: [2-2] 박상현 - React로 개발하는 SPA 실무 이야기
XECon2015 :: [2-2] 박상현 - React로 개발하는 SPA 실무 이야기
 
Front end dev 2016 & beyond
Front end dev 2016 & beyondFront end dev 2016 & beyond
Front end dev 2016 & beyond
 
[114]angularvs react 김훈민손찬욱
[114]angularvs react 김훈민손찬욱[114]angularvs react 김훈민손찬욱
[114]angularvs react 김훈민손찬욱
 
Javascript 생태계
Javascript 생태계Javascript 생태계
Javascript 생태계
 
4-3. jquery
4-3. jquery4-3. jquery
4-3. jquery
 
React 튜토리얼 1차시
React 튜토리얼 1차시React 튜토리얼 1차시
React 튜토리얼 1차시
 
코드잇-리액트-특강.pdf
코드잇-리액트-특강.pdf코드잇-리액트-특강.pdf
코드잇-리액트-특강.pdf
 
웹 프론트엔드 테스팅
웹 프론트엔드 테스팅웹 프론트엔드 테스팅
웹 프론트엔드 테스팅
 
[Codelab 2017] ReactJS 기초
[Codelab 2017] ReactJS 기초[Codelab 2017] ReactJS 기초
[Codelab 2017] ReactJS 기초
 
웹 브라우저는 어떻게 동작하나? (2)
웹 브라우저는 어떻게 동작하나? (2)웹 브라우저는 어떻게 동작하나? (2)
웹 브라우저는 어떻게 동작하나? (2)
 
[Korea Linux Forum] Implementing web based online multiplayer tetris with Ope...
[Korea Linux Forum] Implementing web based online multiplayer tetris with Ope...[Korea Linux Forum] Implementing web based online multiplayer tetris with Ope...
[Korea Linux Forum] Implementing web based online multiplayer tetris with Ope...
 
Meteor 0.3.6 Preview
Meteor 0.3.6 PreviewMeteor 0.3.6 Preview
Meteor 0.3.6 Preview
 
20150912 windows 10 앱 tips tricks
20150912 windows 10 앱 tips  tricks20150912 windows 10 앱 tips  tricks
20150912 windows 10 앱 tips tricks
 
[아꿈사/111105] html5 9장 클라이언트측 데이터로 작업하기
[아꿈사/111105] html5 9장 클라이언트측 데이터로 작업하기[아꿈사/111105] html5 9장 클라이언트측 데이터로 작업하기
[아꿈사/111105] html5 9장 클라이언트측 데이터로 작업하기
 
JQuery를 이용하여 웹 위젯 작성하기_(주)시스포유아이앤씨
JQuery를 이용하여 웹 위젯 작성하기_(주)시스포유아이앤씨JQuery를 이용하여 웹 위젯 작성하기_(주)시스포유아이앤씨
JQuery를 이용하여 웹 위젯 작성하기_(주)시스포유아이앤씨
 
Hacosa jquery 1th
Hacosa jquery 1thHacosa jquery 1th
Hacosa jquery 1th
 
Java script 강의자료_ed13
Java script 강의자료_ed13Java script 강의자료_ed13
Java script 강의자료_ed13
 
자바 웹 개발 시작하기 (5주차 : 스프링 프래임워크)
자바 웹 개발 시작하기 (5주차 : 스프링 프래임워크)자바 웹 개발 시작하기 (5주차 : 스프링 프래임워크)
자바 웹 개발 시작하기 (5주차 : 스프링 프래임워크)
 
Social Tutorial Platform: Webbles
Social Tutorial Platform: Webbles Social Tutorial Platform: Webbles
Social Tutorial Platform: Webbles
 
프로그래밍 패러다임의 진화 및 Spring의 금융권 적용
프로그래밍 패러다임의 진화 및 Spring의 금융권 적용프로그래밍 패러다임의 진화 및 Spring의 금융권 적용
프로그래밍 패러다임의 진화 및 Spring의 금융권 적용
 

More from Taegon Kim

FE로 취업 전에 알았으면 좋았을 것들
FE로 취업 전에 알았으면 좋았을 것들FE로 취업 전에 알았으면 좋았을 것들
FE로 취업 전에 알았으면 좋았을 것들
Taegon Kim
 
프론트엔드 코딩 컨벤션 자동화 도구
프론트엔드 코딩 컨벤션 자동화 도구프론트엔드 코딩 컨벤션 자동화 도구
프론트엔드 코딩 컨벤션 자동화 도구
Taegon Kim
 
Universal Rendering
Universal RenderingUniversal Rendering
Universal Rendering
Taegon Kim
 
React Native를 사용한
 초간단 커뮤니티 앱 제작
React Native를 사용한
 초간단 커뮤니티 앱 제작React Native를 사용한
 초간단 커뮤니티 앱 제작
React Native를 사용한
 초간단 커뮤니티 앱 제작
Taegon Kim
 
ReactJS | 서버와 클라이어트에서 동시에 사용하는
ReactJS | 서버와 클라이어트에서 동시에 사용하는ReactJS | 서버와 클라이어트에서 동시에 사용하는
ReactJS | 서버와 클라이어트에서 동시에 사용하는
Taegon Kim
 
패스트캠퍼스 프론트엔드 강의 오리엔테이션
패스트캠퍼스 프론트엔드 강의 오리엔테이션패스트캠퍼스 프론트엔드 강의 오리엔테이션
패스트캠퍼스 프론트엔드 강의 오리엔테이션
Taegon Kim
 
오늘 당장 시작하는 HTML5
오늘 당장 시작하는 HTML5오늘 당장 시작하는 HTML5
오늘 당장 시작하는 HTML5
Taegon Kim
 
Fiddler: 웹 디버깅 프록시
Fiddler: 웹 디버깅 프록시Fiddler: 웹 디버깅 프록시
Fiddler: 웹 디버깅 프록시
Taegon Kim
 
진화하는 소셜 큐레이션 서비스와 관련 기술
진화하는 소셜 큐레이션 서비스와 관련 기술진화하는 소셜 큐레이션 서비스와 관련 기술
진화하는 소셜 큐레이션 서비스와 관련 기술
Taegon Kim
 
XpressEngine : 보드에서 CMS로
XpressEngine : 보드에서 CMS로XpressEngine : 보드에서 CMS로
XpressEngine : 보드에서 CMS로
Taegon Kim
 
jQuery Trend
jQuery TrendjQuery Trend
jQuery Trend
Taegon Kim
 

More from Taegon Kim (11)

FE로 취업 전에 알았으면 좋았을 것들
FE로 취업 전에 알았으면 좋았을 것들FE로 취업 전에 알았으면 좋았을 것들
FE로 취업 전에 알았으면 좋았을 것들
 
프론트엔드 코딩 컨벤션 자동화 도구
프론트엔드 코딩 컨벤션 자동화 도구프론트엔드 코딩 컨벤션 자동화 도구
프론트엔드 코딩 컨벤션 자동화 도구
 
Universal Rendering
Universal RenderingUniversal Rendering
Universal Rendering
 
React Native를 사용한
 초간단 커뮤니티 앱 제작
React Native를 사용한
 초간단 커뮤니티 앱 제작React Native를 사용한
 초간단 커뮤니티 앱 제작
React Native를 사용한
 초간단 커뮤니티 앱 제작
 
ReactJS | 서버와 클라이어트에서 동시에 사용하는
ReactJS | 서버와 클라이어트에서 동시에 사용하는ReactJS | 서버와 클라이어트에서 동시에 사용하는
ReactJS | 서버와 클라이어트에서 동시에 사용하는
 
패스트캠퍼스 프론트엔드 강의 오리엔테이션
패스트캠퍼스 프론트엔드 강의 오리엔테이션패스트캠퍼스 프론트엔드 강의 오리엔테이션
패스트캠퍼스 프론트엔드 강의 오리엔테이션
 
오늘 당장 시작하는 HTML5
오늘 당장 시작하는 HTML5오늘 당장 시작하는 HTML5
오늘 당장 시작하는 HTML5
 
Fiddler: 웹 디버깅 프록시
Fiddler: 웹 디버깅 프록시Fiddler: 웹 디버깅 프록시
Fiddler: 웹 디버깅 프록시
 
진화하는 소셜 큐레이션 서비스와 관련 기술
진화하는 소셜 큐레이션 서비스와 관련 기술진화하는 소셜 큐레이션 서비스와 관련 기술
진화하는 소셜 큐레이션 서비스와 관련 기술
 
XpressEngine : 보드에서 CMS로
XpressEngine : 보드에서 CMS로XpressEngine : 보드에서 CMS로
XpressEngine : 보드에서 CMS로
 
jQuery Trend
jQuery TrendjQuery Trend
jQuery Trend
 

ReactJS로 시작하는 멀티플랫폼 개발하기

  • 2. 오늘 소개할 내용 • ReactJS • Server-side rendering • React Native • Desktop Web App • React Native Desktop
  • 4. , 0
  • 5. 페이스북, 인스타그램같은 크고 복잡한 애플리케이션 제작을 위한 라이브러리 필요
  • 7. MVC는 적합하지 않음 복잡한 UI에 끊임없이 변하는 M, V ,C가 상호 의존적인 구조 과도하게 연결된 컨트롤러 어디서 변할 지 모르는 모델
  • 8. 어쩌냥.. 아! 재사용 가능한 UI 컴포넌트를 만드는 뷰 전용 라이브러리를 개발하면 되겠고냥 ※ 실제로 고양이가 만든 건 아닙니다
  • 9. a 4
  • 16. 웹은 이 많은 컴 조합입 HTML 일단 여기에 집중해 봅시다
  • 17. jQuery UI 탭 패널을 위해 필요한 HTML 코드 <div id="tabs"> <ul> <li><a href="#fragment-1">One</a></li> <li><a href="#fragment-2">Two</a></li> <li><a href="#fragment-3">Three</a></li> </ul> <div id="fragment-1"> Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. </div> <div id="fragment-2"> Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. </div> <div id="fragment-3"> Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. </div> </div> 웹은 이 많은 컴 조합입 HTML 태그는 충분한가요?
  • 18. 웹은 이 많은 컴 조합입 HTMLjQuery UI 탭 패널을 만들 때 필요한 HTML 코드 <div id="tabs"> <ul> <li><a href="#fragment-1">One</a></li> <li><a href="#fragment-2">Two</a></li> <li><a href="#fragment-3">Three</a></li> </ul> <div id="fragment-1"> Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. </div> <div id="fragment-2"> Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. </div> <div id="fragment-3"> Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. </div> </div>
  • 19. 웹은 이 많은 컴 조합입 HTML <div id="tabs"> <ul> <li><a href="#fragment-1">One</a></li> <li><a href="#fragment-2">Two</a></li> <li><a href="#fragment-3">Three</a></li> </ul> <div id="fragment-1"> Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. </div> <div id="fragment-2"> Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. </div> <div id="fragment-3"> Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. </div> </div> <li>< ListItem이지만 사실은 탭 <div Division이지만 사실은 탭 패널 의미가 맞지 않는 태그를 컴포넌트로 사용심지어 기능을 정의/사용하는 코드(JS)는 별도 파일에 작성
  • 20. 웹은 이 많은 컴 조합입 HTML <div id="tabs"> <ul> <li><a href="#fragment-1">One</a></li> <li><a href="#fragment-2">Two</a></li> <li><a href="#fragment-3">Three</a></li> </ul> <div id="fragment-1"> Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. </div> <div id="fragment-2"> Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. </div> <div id="fragment-3"> Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. </div> </div> <li>< ListItem이지만 사실은 탭 <div Division이지만 사실은 탭 패널 의미가 맞지 않는 태그를 컴포넌트로 사용 심지어 기능을 정의/사용하는 코드(JS)는 별도 파일에 작성
  • 21. 웹은 이 많은 컴 조합입 HTML <div id="tabs"> <ul> <li><a href="#fragment-1">One</a></li> <li><a href="#fragment-2">Two</a></li> <li><a href="#fragment-3">Three</a></li> </ul> <div id="fragment-1"> Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. </div> <div id="fragment-2"> Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. </div> <div id="fragment-3"> Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. </div> </div> <script> jQuery(function($) { $( "#tabs" ).tabs({ active: 1 }); }); </script> 의미가 더 명확한 쪽은? <Tabs selectedIndex={1}> <TabList> <Tab>One</Tab> <Tab>Two</Tab> <Tab>Three</Tab> </TabList> <TabPanel> Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. </TabPanel> <TabPanel> Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. </TabPanel> <TabPanel> Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. </TabPanel> </Tabs>
  • 22. , 0
  • 23. 가상 DOM JSX 문법 단방향 데이터 흐름 Virtual DOM One-way data flow
  • 24. 가상 DOM JSX 문법 단방향 데이터 흐름 - 스토얀 스테파노프, Yahoo YSlow 아키텍트 “자바스크립트에서 DOM 접근은 가능한 최소화하라”
  • 25. 가상 DOM JSX 문법 단방향 데이터 흐름 • 메모리에 가상의 DOM 트리를 구축
  • 26. 가상 DOM JSX 문법 단방향 데이터 흐름 • 값이 변경될 때마다 새로 렌더링 후 이전 트리와 비교 • 메모리에 가상의 DOM 트리를 구축 Before After
  • 27. 가상 DOM JSX 문법 단방향 데이터 흐름 • 값이 변경될 때마다 새로 렌더링 후 이전 트리와 비교 • 메모리에 가상의 DOM 트리를 구축 • 비교 후 실제 변경 사항이 있을 때 변경된 부분만 DOM에 반영 Before After
  • 28. 가상 DOM JSX 문법 단방향 데이터 흐름 • 값이 변경될 때마다 새로 렌더링 후 이전 트리와 비교 • 메모리에 가상의 DOM 트리를 구축 • 비교 후 실제 변경 사항이 있을 때 변경된 부분만 DOM에 반영 • 임의의 두 트리를 비교하는 최소 횟수는 O(n^3),
 React에서는 같은 레벨의 트리만 비교하여 O(n)으로 최적화 Before After
  • 29. 가상 DOM JSX 문법 단방향 데이터 흐름 • 값이 변경될 때마다 새로 렌더링 후 이전 트리와 비교 • 메모리에 가상의 DOM 트리를 구축 • 비교 후 실제 변경 사항이 있을 때 변경된 부분만 DOM에 반영 • 임의의 두 트리를 비교하는 최소 횟수는 O(n^3),
 React에서는 같은 레벨의 트리만 비교하여 O(n)으로 최적화 • 그 밖에도 목록 항목의 키 비교, 컴포넌트 비교, 배치 잡, 
 자동 이벤트 위임, 선택적 하위 트리 렌더링 등을 통해
 노력 대비 꽤 나은 성능 보장 Before After
  • 30. 가상 DOM JSX 문법 단방향 데이터 흐름 • 값이 변경될 때마다 새로 렌더링 후 이전 트리와 비교 • 메모리에 가상의 DOM 트리를 구축 • 비교 후 실제 변경 사항이 있을 때 변경된 부분만 DOM에 반영 • 임의의 두 트리를 비교하는 최소 횟수는 O(n^3),
 React에서는 같은 레벨의 트리만 비교하여 O(n)으로 최적화 • 그 밖에도 목록 항목의 키 비교, 컴포넌트 비교, 배치 잡, 
 자동 이벤트 위임, 선택적 하위 트리 렌더링 등을 통해
 노력 대비 꽤 나은 성능 보장 React.js Conf 2015 - Hype! | http://youtu.be/z5e7kWSHWTg?t=4m10s Angular ReactEmber
  • 31. 가상 DOM JSX 문법 단방향 데이터 흐름 • 값이 변경될 때마다 새로 렌더링 후 이전 트리와 비교 • 메모리에 가상의 DOM 트리를 구축 • 비교 후 실제 변경 사항이 있을 때 변경된 부분만 DOM에 반영 • 임의의 두 트리를 비교하는 최소 횟수는 O(n^3),
 React에서는 같은 레벨의 트리만 비교하여 O(n)으로 최적화 • 그 밖에도 목록 항목의 키 비교, 컴포넌트 비교, 배치 잡, 
 자동 이벤트 위임, 선택적 하위 트리 렌더링 등을 통해
 노력 대비 꽤 나은 성능 보장 • Google은 2015년 7월에 Incremental DOM이라는 
 Virtual DOM 라이브러리 발표 • Ember는 Glimmer라는 Virtual DOM 기술 적용 Virtual DOM != Silver Bullet Angular 2 alpha 버전은 Virtual DOM 없이 더 나은 성능을 구현 그래도 꽤 나은 선택 http://goo.gl/k4pYbH
  • 32. 가상 DOM JSX 문법 단방향 데이터 흐름 • 값이 변경될 때마다 새로 렌더링 후 이전 트리와 비교 • 메모리에 가상의 DOM 트리를 구축 • 비교 후 실제 변경 사항이 있을 때 변경된 부분만 DOM에 반영 • 임의의 두 트리를 비교하는 최소 횟수는 O(n^3),
 React에서는 같은 레벨의 트리만 비교하여 O(n)으로 최적화 • 그 밖에도 목록 항목의 키 비교, 컴포넌트 비교, 배치 잡, 
 자동 이벤트 위임, 선택적 하위 트리 렌더링 등을 통해
 노력 대비 꽤 나은 성능 보장
  • 33. 가상 DOM JSX 문법 단방향 데이터 흐름 • 자바스크립트 안에 XML을 표현하는 문법 var app = <Nav color="blur" />; • 자바스크립트 코드로 변환해서 사용 var app = React.createElement(Nav, {color:"blue"}); • 속성 표현을 통해 문자열은 물론 자바스크립트 값을 그대로 전달 var app = <Nav color="blur" checked={true} name={name||"!"} />; • 필수는 아니지만 거의 모든 React 프로젝트가 사용 중
  • 34. 가상 DOM JSX 문법 단방향 데이터 흐름 • 데이터는 상위 컴포넌트에서 하위 컴포넌트로만 흐름 • 상위에서 전달받은 값(props)은 수정 불가(immutable) • 상위 컴포넌트는 하위 컴포넌트의 이벤트를 전달받아 업데이트 • 컴포넌트 내부의 상태는 스테이트(state)에 저장 • Flux: 애플리케이션 수준에서 적용한 단방향 데이터 흐름
  • 35. c
  • 36. var React = require('react'); var ReactDOM = require('react-dom'); var App = React.createClass({ render: function(){ return <h1>Hello, world!</h1>; } }); ReactDOM.render(   <App list={[1, 2, 3]} />,   document.getElementById('example') );
  • 37. var React = require('react'); var ReactDOM = require('react-dom'); var App = React.createClass({ render: function(){ return <h1>Hello, world!</h1>; } }); ReactDOM.render(   <App list={[1, 2, 3]} />,   document.getElementById('example') ); require('react') require('react-dom') Node.js와 같은 CommonJS 방식 사용
  • 38. var React = require('react'); var ReactDOM = require('react-dom'); var App = React.createClass({ render: function(){ return <h1>Hello, world!</h1>; } }); ReactDOM.render(   <App list={[1, 2, 3]} />,   document.getElementById('example') ); <h1>Hello, world!</h1> JS에 XML을 바로 쓰는 JSX 문법
  • 39. var React = require('react'); var ReactDOM = require('react-dom'); var App = React.createClass({ render: function(){ return <h1>Hello, world!</h1>; } }); ReactDOM.render(   <App list={[1, 2, 3]} />,   document.getElementById('example') ); <App list={[1, 2, 3]} />, 컴포넌트에 프로퍼티 전달(객체도 가능)
  • 40. <!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>Hello React!</title> <script src="build/react.js"></script> <script src="build/react-dom.js"></script> <script src="libs/babel-core/5.8.23/browser.min.js"></script> </head> <body> <div id="example"></div> <script type="text/babel"> var App = React.createClass({ render: function(){ return <h1>Hello, world!</h1>; } }); ReactDOM.render( <App list={[1, 2, 3]} />, document.getElementById('example') ); </script> </body> </html> 브라우저에서 해석하게 할 수도 있지만… 번거롭고 불러오는 파일 많고 성능 안 좋고…
  • 41. 보통 프론트엔드 도구를 사용해 미리 변환
  • 42. var React = require('react'); var ReactDOM = require('react-dom'); var App = React.createClass({ render: function(){ return <h1>Hello, world!</h1>; } }); ReactDOM.render(   <App list={[1, 2, 3]} />,   document.getElementById('example') ); 프론트엔드 도구를 사용하면
  • 43. import React, { Component } from 'react'; import ReactDOM from 'react-dom'; class App extends Component { render() { return <h1>Hello, world!</h1>; } } ReactDOM.render(   <App list={[1, 2, 3]} />,   document.getElementById('example') ); ES2015도 이렇게 쓸 수 있습니다
  • 44. c
  • 45. var React = require('react'); var ReactDOM = require('react-dom'); var Link = React.createClass({ render: function() { return <a href={"/path/to/"+this.props.num}>Link</a>; } }); var App = React.createClass({ render: function(){ return ( <div> <h1>Hello, world!</h1> <Link num={this.props.list[1]} /> </div> ); } }); ReactDOM.render(   <App list={[1, 2, 3]} />,   document.getElementById('example') );
  • 46. var React = require('react'); var ReactDOM = require('react-dom'); var Link = React.createClass({ render: function() { return <a href={"/path/to/"+this.props.num}>Link</a>; } }); var App = React.createClass({ render: function(){ return ( <div> <h1>Hello, world!</h1> <Link num={this.props.list[1]} /> </div> ); } }); ReactDOM.render(   <App list={[1, 2, 3]} />,   document.getElementById('example') ); <App list={[1, 2, 3]} /> <Link num={this.props.list[1]} /> this.props.num 데이터는 위에서 아래로 흐른다.
  • 47. ReactDOM.render(   <App list={[1, 2, 3]} />,   document.getElementById('example') ); var React = require('react'); var ReactDOM = require('react-dom'); var Link = React.createClass({ render: function() { return <a href={"/path/to/"+this.props.num}>Link</a>; }. }); var App = React.createClass({ render: function(){ return ( <div> <h1>Hello, world!</h1> <Link num={this.props.list[1]} /> </div> ); }. });
  • 48. ReactDOM.render(   <App list={[1, 2, 3]} />,   document.getElementById('example') var ReactDOM = require('react-dom'); var Link = React.createClass({ render: function() { return <a href={"/path/to/"+this.props.num}>Link</a>; }. }); var App = React.createClass({ render: function(){ return ( <div> <h1>Hello, world!</h1> <Link num={this.props.list[1]} /> </div> ); }. });
  • 49. var Link = React.createClass({ render: function() { return <a href={"/path/to/"+this.props.num}>Link</a>; }. }); var App = React.createClass({var App = React.createClass({ handleClick: function(event) { this.setState({clickedElement: event.target}); }, render: function(){ return ( <div> <h1>Hello, world!</h1> <Link num={this.props.list[1]} onClick={this.handleClick} /> </div> ); } });
  • 50. var Link = React.createClass({ render: function() { return <a href={"/path/to/"+this.props.num} onClick={this.props.onClick}>Link</a>; }. }); var App = React.createClass({ handleClick: function(event) { this.setState({clickedElement: event.target}); }, render: function(){ return ( <div> <h1>Hello, world!</h1> <Link num={this.props.list[1]} onClick={this.handleClick} /> </div> ); } });
  • 51. var Link = React.createClass({ render: function() { return <a href={"/path/to/"+this.props.num} onClick={this.props.onClick}>Link</a>; }. }); var App = React.createClass({ handleClick: function(event) { this.setState({clickedElement: event.target}); }, render: function(){ return ( <div> <h1>Hello, world!</h1> <Link num={this.props.list[1]} onClick={this.handleClick} /> </div> ); } }); onClick={this.props.onClick} onClick={this.handleClick} handleClick: function(event) { this.setState({clickedElement: event.target}); }, 이벤트를 통해 하위 컴포넌트가 상위 컴포넌트에 값을 전달할 수 있다
  • 52. c4 ?
  • 53. 이미 많은 서비스가 React 사용 중
  • 54. 심지어 페이스북은 알파 버전 사용 중!
  • 55. 참고자료 https://taegon.kim/archives/5288 Flux와 Redux http://www.slideshare.net/jeokrang/facebook-react-55649927 Facebook은 React를 왜 만들었을까? http://webframeworks.kr/tutorials/react/es2015-react/ ES2015와 React http://webframeworks.kr/tutorials/react/getting-started/ React 시작하기
  • 57. 성능 페이지 로딩 + 자바스크립트 로딩 + 렌더링 =
 초기 구동 속도가 느리다 검색 엔진 최적화 자바스크립트를 실행하지 못하는 크롤러는
 페이지의 콘텐츠를 수집하지 못한다 클라이언트 렌더링의 성능
 매번 전체 페이지를 다시 읽는 것보다 빠름 사용자 경험
 자연스럽게 연결되는 사용자 경험 가능 코드의 일관성
 렌더링 책임은 한 쪽에만 주는 편이 일관성 유지가 쉬움 장점 단점
  • 58. 성능
 페이지 로딩 + JS 로딩 + 렌더링 (+ 데이터 로딩)=
 초기 구동 속도가 느림 검색 엔진 최적화
 자바스크립트를 실행하지 못하는 크롤러는
 페이지의 콘텐츠를 수집하지 못함 단점클라이언트 렌더링의
  • 60. + 서버 렌더링클라이언트 렌더링 빈 페이지 App HTML 문서 전송 JS 전송 후 렌더링빈 콘텐츠를 볼 수 없음
  • 61. 클라이언트 렌더링 App + 서버 렌더링 JS 전송 후 DOM에 붙음 HTML 문서 전송 렌더링된 콘텐츠는 볼 수 있지만, 인터랙션은 아직 동작 안함
  • 62. R
  • 63. 사용자가 느끼는 웹 사이트 반응 속도는 콘텐츠를 처음 본 시간에 영향을 받는다
  • 64. c
  • 65. import React, { Component } from 'react'; import ReactDOM from 'react-dom'; class App extends Component { render() { return <h1>Hello, world!</h1>; } } ReactDOM.render(   <App list={[1, 2, 3]} />,   document.getElementById('example') ); 앞서 살펴 본 클라이언트 코드
  • 66. import React, { Component } from 'react'; import ReactDOM from 'react-dom'; class App extends Component { render() { return <h1>Hello, world!</h1>; } } ReactDOM.render(   <App list={[1, 2, 3]} />,   document.getElementById('example') ); ReactDOM은 브라우저 환경에만 해당 import ReactDOM from 'react-dom'; ReactDOM.render
  • 67. import ReactDOM from 'react-dom'; import React, { Component } from 'react'; import ReactDOM from 'react-dom'; class App extends Component { render() { return <h1>Hello, world!</h1>; } } ReactDOM.render(   <App list={[1, 2, 3]} />,   document.getElementById('example') ); DOM 관련 부분만 별도 파일로 분리 import ReactDOM from 'react-dom'; ReactDOM.render import React, { Component } from 'react'; ReactDOM.render(   <App list={[1, 2, 3]} />,   document.getElementById('example') ); class App extends Component { render() { return <h1>Hello, world!</h1>; } }
  • 68. import ReactDOM from 'react-dom'; DOM 관련 부분만 별도 파일로 분리 import React, { Component } from 'react'; ReactDOM.render(   <App list={[1, 2, 3]} />,   document.getElementById('example') ); export default App; import App from './App'; browser.js App.js class App extends Component { render() { return <h1>Hello, world!</h1>; } }
  • 69. import ReactDOM from 'react-dom'; DOM 관련 부분만 별도 파일로 분리 import React, { Component } from 'react'; class App extends Component { render() { return <h1>Hello, world!</h1>; } } ReactDOM.render(   <App list={[1, 2, 3]} />,   document.getElementById('example') ); export default App; import App from './App'; browser.js App.js
  • 70. import ReactServer from 'react-dom/server'; 서버 렌더링은 react-dom/server 사용 import React, { Component } from 'react'; class App extends Component { render() { return <h1>Hello, world!</h1>; } } var result = ReactServer.renderToString(   <App list={[1, 2, 3]} /> ); export default App; import App from './App'; server.js App.js
  • 71. import ReactServer from 'react-dom/server'; 결과물을 HTML 페이지에 출력 <body> <div id="example"> {{result}} </div> </body> var result = ReactServer.renderToString(   <App list={[1, 2, 3]} /> ); import App from './App'; server.js index.html
  • 72. import ReactServer from 'react-dom/server'; 결과물을 HTML 페이지에 출력 <body> <div id="example"> {{result}} </div> </body> var result = ReactServer.renderToString(   <App list={[1, 2, 3]} /> ); import App from './App'; server.js index.html {{result}} result
  • 74. Isomorphic JavaScript 서버와 클라이언트가 같은 코드를 공유하는 개발 방식같은 코드를 공유 Client Server 공통 코드
  • 75. Isomorphic JavaScript 서버와 클라이언트가 같은 코드를 공유하는 개발 방식 Client Server React 같은 코드를 공유
  • 76. 참고자료 https://taegon.kim/archives/5312 React 애플리케이션의 서버 렌더링 http://isomorphic.net/ React를 비롯한 Isomorphic JavaScript 라이브러리를 소개하는 곳 http://augustl.com/blog/2014/jdk8_react_rendering_on_server/ JDK8(Clojure)에서 React 렌더링하는 법 (영문) http://www.phpied.com/server-side-react-with-php/ PHP 서버에서 React 렌더링하는 법 (영문)
  • 78. Virtual DOM DOM Virtual DOM의 결과물은 DOM이 될 수도 있지만
  • 79. Virtual DOM DOM SVG Canvas "string" 문자열, SVG, Canvas 등으로 확장 가능
  • 80. 예제: React ART ... renderGraphic: function(rotation) { return ( <Group onMouseDown={this.handleMouseDown} onMouseUp={this.handleMouseUp}> <Group x={210} y={135}> <Shape fill="rgba(0,0,0,0.1)" d={BORDER_PATH} /> <Shape fill="#7BC7BA" d={BG_PATH} /> <Shape fill="#DCDCDC" d={BAR_PATH} /> <Shape fill="#D97B76" d={RED_DOT_PATH} /> <Shape fill="#DBBB79" d={YELLOW_DOT_PATH} /> <Shape fill="#A6BD8A" d={GREEN_DOT_PATH} /> <Group x={55} y={29}> <Group rotation={rotation} originX={84} originY={89}> <Shape fill="#FFFFFF" d={CENTER_DOT_PATH} /> <Group> <Shape d={RING_ONE_PATH} stroke="#FFFFFF" strokeWidth={8} /> <Shape d={RING_TWO_PATH} transform={RING_TWO_ROTATE} stroke="#FFFFFF" strokeWidth={8} /> <Shape d={RING_THREE_PATH} transform={RING_THREE_ROTATE} stroke="#FFFFFF" strokeWidth={8} /> </Group> </Group> </Group> </Group> </Group> ); } ...
  • 82. Virtual DOM DOM SVG Canvas "string" 문자열, SVG, Canvas 등으로 확장 가능
  • 83. Virtual DOM Native Component 네이티브 컴포넌트로 확장할 수도 있음
  • 84. H 4
  • 85. 네이티브 컴포넌트 비동기 실행 Flexbox 레이아웃 폴리필(Polyfill) 간편한 네이티브 확장
  • 86. 네이티브 컴포넌트 비동기 실행 Flexbox 레이아웃 폴리필(Polyfill) 간편한 네이티브 확장 <header> <footer>, <section> <div> <span> <img> <a> <strong> <em> <form> <select> <input> <textarea> <button> ... <View> <Text> <Image> <ScrollView> <ListView> <WebView> <PickerIOS> <NavigatorIOS> <ActivityIndicatorIOS> <ProgressViewIOS> <SwitchIOS>... <View> <Text> <Image> <ScrollView> <ListView> <WebView> <DrawerLayoutAndroid> <ProgressBarAndroid> <SwitchAndroid> <ViewPagerAndroid> ...
  • 87. 네이티브 컴포넌트 비동기 실행 Flexbox 레이아웃 폴리필(Polyfill) 간편한 네이티브 확장 • 자바스크립트는 네이티브보다 훨씬 느리기 때문에 동기 실행시 네이티브 UI와 자바스크립트 간의 병목 현상 발생 • 네이티브와 자바스크립트 사이에 메시지 큐를 두어 비동기 실행 JS VM Native Java/C++/ObjC/Switft
  • 88. 비동기 실행 Flexbox 레이아웃 폴리필(Polyfill) 간편한 네이티브 확장 • CSS와 구조가 비슷한 StyleSheet 객체 사용 • CSS3 Flexbox와 비슷한 방식으로 레이아웃 스타일링 var ReactNative = React.createClass({ render: function() { return ( <View style={styles.row}> <View style={styles.text}> <Text style={styles.title}>React Native</Text> <Text style={styles.subtitle}>Build mobile apps using React</Text> </View> </View> ); }, }); var styles = StyleSheet.create({ row: { flexDirection: 'row', margin: 40 }, text: { flex: 1, justifyContent: 'center'}, title: { fontSize: 11, fontWeight: 'bold' }, subtitle: { fontSize: 10 }, });
  • 89. xbox 레이아웃 폴리필(Polyfill) 간편한 네이티브 확장 • XHR, requestAnimationFrame, navigator.geolocation 등 익숙한 자바스크립트 기능 제공 var GeoInfo = React.createClass({ getInitialState: function() { return { position: 'unknown' }; }, componentDidMount: function() { navigator.geolocation.getCurrentPosition( (position) => this.setState({position}), (error) => console.error(error) ); }, render: function() { return ( <Text> Position: {JSON.stringify(this.state.position)} </Text> ); }, });
  • 90. 리필(Polyfill) 간편한 네이티브 확장 • Java(Android), ObjectiveC/Swift (iOS)로 작성된
 네이티브 모듈을 손쉽게 자바스크립트 모듈로 바인딩 // Java public class MyCustomModule extends ReactContextBaseJavaModule { // Available as NativeModules.MyCustomModule.processString @ReactMethod public void processString(String input, Callback callback) { callback.invoke(input.replace("Goodbye", "Hello")); } } // JavaScript ... componentDidMount() { NativeModules.MyCustomModule.processString(this.state.text, (text) => { this.setState({text}); }); }, ...
  • 92. $ brew install node watchman $ node install -g react-native-cli 필요한 패키지 설치 (Xcode 및 안드로이드 SDK 필수) 프로젝트 생성 $ react-native init HelloWorld 프로젝트 오픈 후 컴파일 $ cd HellWorld $ open ios/HelloWorld.xcodeproj (iOS) $ react-native run-android (Android) 코드는 index.{ios, android}.js 파일 수정
  • 94. 데모 • 기본 네이티브 컴포넌트만 사용 • React에 익숙하지 않은 상태에서
 대략 20시간 소요 • 네이티브와 똑같은 무한 스크롤 성능 https://www.youtube.com/watch?v=fRaC9jECxCg
  • 95. 페이스북의 AdManager 개발 사례 • iOS 개발 후 안드로이드 버전 개발 • 각 플랫폼에 맞는 네이티브 룩앤필 • 전체 코드의 85% 가량을 재사용 • 두 플랫폼의 저장소 통합 관리
  • 98. JS 모르고 jQuery만 알면 되던가요? 결국 네이티브라는 장애물을 넘어야 합니다.
  • 99. 물론 남이 삽질해주길 기다리는 방법도 있죠
  • 101. 참고자료 https://realm.io/kr/news/react-native/ 리액트 네이티브로 시작하는 앱 개발 #1 http://react.parts/ React 네이티브 컴포넌트 https://rnplay.org/ React Native Playground
  • 103. 이미 거의 끝났습니다. 웹 앱이 완성됐다면 데스크톱 앱은
  • 104. 약간의 양념만 있으면 되쥬. 솨아~
  • 106. 은.. 크로미움 엔진과 Node.js가 합쳐진 데스크톱 애플리케이션 런타임
  • 107. 은.. 코드 하나로 맥, 리눅스, 윈도우 플랫폼과 32/64비트 모두 지원 </>
  • 108. 이미 많은 기업에서 사용 중 은..
  • 109. 최근 워드프레스는 Calypso라는 프로젝트를 통해 wordpress.com의 프론트엔드를 모두 대체
  • 110. React + Node.js 서버를 사용한 Isomorphic JavaScript 동일한 코드를 Desktop App에도 사용
  • 111. React 앱 패키징 $ npm install -g electron-packager
 $ cd HelloWorld $ electron-packager . HelloWorldApp --platform=all --arch=x64 --version=0.35.4 HelloWorld ├─ package.json └┬ src ├─ index.html ├─ main.js ├─ other.js └─ style.css 폴더 구조를 왼쪽과 같이 작성한 후... 단, OS X / Linux에서 Windows 앱을 빌드하려면 wine 필요wine
  • 112. 참고 자료 https://github.com/chentsulin/electron-react-boilerplate Electron과 React를 사용한 데스크톱 앱 프로젝트 시작 틀 https://github.com/sindresorhus/awesome-electron Electron 관련 정보를 모아 둔 페이지 https://github.com/gabrielbull/react-desktop 데스크톱 환경에 사용할 수 있는 React UI 컴포넌트 모음
  • 114. 그래도 네이티브가 더 좋다면? image from 이말년씨리즈 데스크톱 웹 앱 좋은 거 알겠는데
  • 115. 데스크톱 네이티브? 원한다면 주도록 하지 잘 찾아봐. GitHub에 두고 왔으니… image from 원피스
  • 116. React Native를 포크한 프로젝트라 사용법도 비슷합니다 예제 실행방법 $ git clone https://github.com/ptmt/react-native-desktop
 $ cd react-native-desktop && npm install Examples 아래의 원하는 폴더로 가서 .xcodeproj 파일을 XCode에서 열고 컴파일
  • 117. Hello World 앱 크기 비교 React Native Desktop 3.5MB 105.3MB (OS X 빌드 기준)
  • 119. 윈도우 버전도 없고 (OSX만 지원) image from 수퍼마리오
  • 121. 실무에는 절대로 사용하지 마세요! 개발 초기라 매우 불안정하니
  • 123. Once, WriteLearn Anywhere 한 번 배워 어디서나 개발하자
  • 125. Credits Twitter and Wordpress icons are made by Freepik from www.flaticon.com All images without any notes are published under Creative Commons zero. All videos are published under Creative Commons zero.