react.js + reduxで作るspa
TRANSCRIPT
![Page 1: React.js + Reduxで作るSPA](https://reader036.vdocuments.mx/reader036/viewer/2022062412/5871b0b51a28abda6a8b6877/html5/thumbnails/1.jpg)
React.js + Reduxで作るSPA
@saekis
![Page 2: React.js + Reduxで作るSPA](https://reader036.vdocuments.mx/reader036/viewer/2022062412/5871b0b51a28abda6a8b6877/html5/thumbnails/2.jpg)
@saekis
• 91年生まれ (25歳 )• Software engineer
![Page 3: React.js + Reduxで作るSPA](https://reader036.vdocuments.mx/reader036/viewer/2022062412/5871b0b51a28abda6a8b6877/html5/thumbnails/3.jpg)
SPAとは“A single-page application (SPA) is a web application that fits on a single web page providing a more fluid user experience similar to a desktop application”
出典 : Wikipedia
![Page 4: React.js + Reduxで作るSPA](https://reader036.vdocuments.mx/reader036/viewer/2022062412/5871b0b51a28abda6a8b6877/html5/thumbnails/4.jpg)
従来のweb• ページ遷移の度にサーバへ HTTPリクエスト• その度に HTMLや assetsファイルをダウンロード、そして DOMの生成• 必要に応じて ajaxを使う• 遅い
![Page 5: React.js + Reduxで作るSPA](https://reader036.vdocuments.mx/reader036/viewer/2022062412/5871b0b51a28abda6a8b6877/html5/thumbnails/5.jpg)
SPA• ページ遷移の度にブラウザをリロードさせず、コンテンツとなる DOMの更新のみ行う• HTMLや assetsファイルのダウンロードは初回リクエスト時のみ• 必要なデータを ajaxで取得• 速い• ネイティブアプリ
![Page 6: React.js + Reduxで作るSPA](https://reader036.vdocuments.mx/reader036/viewer/2022062412/5871b0b51a28abda6a8b6877/html5/thumbnails/6.jpg)
React.js
![Page 7: React.js + Reduxで作るSPA](https://reader036.vdocuments.mx/reader036/viewer/2022062412/5871b0b51a28abda6a8b6877/html5/thumbnails/7.jpg)
![Page 8: React.js + Reduxで作るSPA](https://reader036.vdocuments.mx/reader036/viewer/2022062412/5871b0b51a28abda6a8b6877/html5/thumbnails/8.jpg)
リリースから 3年
![Page 9: React.js + Reduxで作るSPA](https://reader036.vdocuments.mx/reader036/viewer/2022062412/5871b0b51a28abda6a8b6877/html5/thumbnails/9.jpg)
みなさん、 React書いてますか?
![Page 10: React.js + Reduxで作るSPA](https://reader036.vdocuments.mx/reader036/viewer/2022062412/5871b0b51a28abda6a8b6877/html5/thumbnails/10.jpg)
MVC
![Page 11: React.js + Reduxで作るSPA](https://reader036.vdocuments.mx/reader036/viewer/2022062412/5871b0b51a28abda6a8b6877/html5/thumbnails/11.jpg)
React.jsとは• Facebook製• UI描画のためのライブラリ• Component -> VirtualDOM -> DOM
![Page 12: React.js + Reduxで作るSPA](https://reader036.vdocuments.mx/reader036/viewer/2022062412/5871b0b51a28abda6a8b6877/html5/thumbnails/12.jpg)
VirtualDOM??
![Page 13: React.js + Reduxで作るSPA](https://reader036.vdocuments.mx/reader036/viewer/2022062412/5871b0b51a28abda6a8b6877/html5/thumbnails/13.jpg)
VirtualDOM??
VirtualDOM Tree VirtualDOM Tree
DOM Tree
差分を計算
反映
![Page 14: React.js + Reduxで作るSPA](https://reader036.vdocuments.mx/reader036/viewer/2022062412/5871b0b51a28abda6a8b6877/html5/thumbnails/14.jpg)
VirtualDOM??
VirtualDOM Tree VirtualDOM Tree差分を計算
反映
<div>hoge</div><div>foo</div>
<div>hoge</div><div>piyo</div>
<div>hoge</div><div>piyo</div>
![Page 15: React.js + Reduxで作るSPA](https://reader036.vdocuments.mx/reader036/viewer/2022062412/5871b0b51a28abda6a8b6877/html5/thumbnails/15.jpg)
VirtualDOM??
• 仮想 DOMとして現在の DOMの状態を記憶• レンダー前の仮想 DOMと現在の仮想 DOMの差分を計算• 差分のみ DOMに反映
![Page 16: React.js + Reduxで作るSPA](https://reader036.vdocuments.mx/reader036/viewer/2022062412/5871b0b51a28abda6a8b6877/html5/thumbnails/16.jpg)
JSX
![Page 17: React.js + Reduxで作るSPA](https://reader036.vdocuments.mx/reader036/viewer/2022062412/5871b0b51a28abda6a8b6877/html5/thumbnails/17.jpg)
JSX
• HTMLタグっぽい何か• JSのコードに HTMLっぽい定義をするための言語
![Page 18: React.js + Reduxで作るSPA](https://reader036.vdocuments.mx/reader036/viewer/2022062412/5871b0b51a28abda6a8b6877/html5/thumbnails/18.jpg)
JSXimport React from 'react'
export default class CommentBox extends React.Component { render() { return ( <div className="commentBox"> Hello, world! I am a CommentBox. </div> ) }}
![Page 19: React.js + Reduxで作るSPA](https://reader036.vdocuments.mx/reader036/viewer/2022062412/5871b0b51a28abda6a8b6877/html5/thumbnails/19.jpg)
JSXimport React from 'react'
export default class CommentBox extends React.Component { render() { return ( <div className="commentBox"> Hello, world! I am a CommentBox. </div> ) }}
![Page 20: React.js + Reduxで作るSPA](https://reader036.vdocuments.mx/reader036/viewer/2022062412/5871b0b51a28abda6a8b6877/html5/thumbnails/20.jpg)
JSXimport React from 'react'
export default class CommentBox extends React.Component { render() { return ( <div className="commentBox"> Hello, world! I am a CommentBox. </div> ) }}
var div = document.createElement("div");div.className = 'commentBox';div.innerHTML = "Hello, world! I am a CommentBox.";
変換
![Page 21: React.js + Reduxで作るSPA](https://reader036.vdocuments.mx/reader036/viewer/2022062412/5871b0b51a28abda6a8b6877/html5/thumbnails/21.jpg)
JSX• ブラウザに JSとして解釈させるためにはコンパイルが必要• JSX -> browserify, babelify -> JS• browzerifyはブラウザ上でも Node.jsのモジュールを使えるようにするために使う• babelifyは ES6->ES5の変換、 JSX->JSの変換をするために使う
![Page 22: React.js + Reduxで作るSPA](https://reader036.vdocuments.mx/reader036/viewer/2022062412/5871b0b51a28abda6a8b6877/html5/thumbnails/22.jpg)
JSX -> JSimport gulp from 'gulp'import browserify from 'browserify'import babelify from 'babelify'import source from 'vinyl-source-stream'import duration from 'gulp-duration'
gulp.task('browserify', () => { return browserify({entries: [“./react/app.js“]}) .transform(babelify, {presets: ["es2015", "react"], plugins: ["babel-plugin-transform-object-assign"]}) .bundle() .pipe(source('bundle.js')) .pipe(gulp.dest(config.dest + '/react')) .pipe(duration('browserify'))})
![Page 23: React.js + Reduxで作るSPA](https://reader036.vdocuments.mx/reader036/viewer/2022062412/5871b0b51a28abda6a8b6877/html5/thumbnails/23.jpg)
Redux
![Page 24: React.js + Reduxで作るSPA](https://reader036.vdocuments.mx/reader036/viewer/2022062412/5871b0b51a28abda6a8b6877/html5/thumbnails/24.jpg)
![Page 25: React.js + Reduxで作るSPA](https://reader036.vdocuments.mx/reader036/viewer/2022062412/5871b0b51a28abda6a8b6877/html5/thumbnails/25.jpg)
Redux• Fluxアーキテクチャに基づいて設計された
Javascriptフレームワーク• Facebookも Fluxフレームワークの中では
Reduxを使うことを推奨している(たぶん)
![Page 26: React.js + Reduxで作るSPA](https://reader036.vdocuments.mx/reader036/viewer/2022062412/5871b0b51a28abda6a8b6877/html5/thumbnails/26.jpg)
Flux?
![Page 27: React.js + Reduxで作るSPA](https://reader036.vdocuments.mx/reader036/viewer/2022062412/5871b0b51a28abda6a8b6877/html5/thumbnails/27.jpg)
Flux?
![Page 28: React.js + Reduxで作るSPA](https://reader036.vdocuments.mx/reader036/viewer/2022062412/5871b0b51a28abda6a8b6877/html5/thumbnails/28.jpg)
Flux?• アーキテクチャ (設計思想 )• データは必ず一方向にしか流れないように設計される• Action -> Dispatcher -> Store -> View ->
Action -> …
![Page 29: React.js + Reduxで作るSPA](https://reader036.vdocuments.mx/reader036/viewer/2022062412/5871b0b51a28abda6a8b6877/html5/thumbnails/29.jpg)
Redux• Fluxアーキテクチャに基づいて設計された
Javascriptフレームワーク
![Page 30: React.js + Reduxで作るSPA](https://reader036.vdocuments.mx/reader036/viewer/2022062412/5871b0b51a28abda6a8b6877/html5/thumbnails/30.jpg)
Redux
![Page 31: React.js + Reduxで作るSPA](https://reader036.vdocuments.mx/reader036/viewer/2022062412/5871b0b51a28abda6a8b6877/html5/thumbnails/31.jpg)
React + ReduxでSPAをつくる
![Page 32: React.js + Reduxで作るSPA](https://reader036.vdocuments.mx/reader036/viewer/2022062412/5871b0b51a28abda6a8b6877/html5/thumbnails/32.jpg)
SPAをつくる• Reactコンポーネント• route定義• reducer• Redux state -> React prop
![Page 33: React.js + Reduxで作るSPA](https://reader036.vdocuments.mx/reader036/viewer/2022062412/5871b0b51a28abda6a8b6877/html5/thumbnails/33.jpg)
route定義import { Provider } from 'react-redux'import { Router, Route, IndexRoute, browserHistory } from 'react-router'
<Provider store={store}> <Router history={history}> <Route path="/hoge" component={Index} > <Route path="foo" component={FooContainer}></Route> <Route path="piyo" component={PiyoContainer} ></Route> </Route> </Router></Provider>
![Page 34: React.js + Reduxで作るSPA](https://reader036.vdocuments.mx/reader036/viewer/2022062412/5871b0b51a28abda6a8b6877/html5/thumbnails/34.jpg)
react-redux• Reduxの” state”と Reactの” prop”をつなぐ• 明示的に書かなくても、 stateの更新を
componentが subscribeしてくれる
![Page 35: React.js + Reduxで作るSPA](https://reader036.vdocuments.mx/reader036/viewer/2022062412/5871b0b51a28abda6a8b6877/html5/thumbnails/35.jpg)
react-reduximport { connect } from ‘react-redux'import hogeComponent from '../components/hoge'
function mapStateToProps(state) { return { user: state.user }}
function mapDispatchToProps(dispatch) { return { hoge: () => { dispatch(hoge()) }, foo: () => { dispatch(foo()) } }}
export default connect(mapStateToProps, mapDispatchToProps)(hogeComponent)
![Page 36: React.js + Reduxで作るSPA](https://reader036.vdocuments.mx/reader036/viewer/2022062412/5871b0b51a28abda6a8b6877/html5/thumbnails/36.jpg)
実務で使ってみた感想
![Page 37: React.js + Reduxで作るSPA](https://reader036.vdocuments.mx/reader036/viewer/2022062412/5871b0b51a28abda6a8b6877/html5/thumbnails/37.jpg)
実務で使ってみた感想• テストがしやすい• Reduxのコード量がとにかく多くなる感じ• 特に action createrの肥大化
![Page 38: React.js + Reduxで作るSPA](https://reader036.vdocuments.mx/reader036/viewer/2022062412/5871b0b51a28abda6a8b6877/html5/thumbnails/38.jpg)
ご清聴ありがとうございました