View
191
Download
6
Category
Preview:
Citation preview
実践 Redux Saga-Practical Redux Saga-
2017/01/27( 金 )スタジオ アルカナ 社内勉強会 ・ #21
よしだ しんいちろう
自己紹介
name: “ よしだ しんいちろう”age: 32worksAt: “Studio Arcana co.,Ltd.”roles: [ “Web Application Developer”, “Management” ]twitter: “@yossy222” graduated: [ “Advanced Institute of Industrial Technology”, “National Institute of Technology, Kushiro College” ]
2
自己紹介
Prototype.js/script.aculo.us (2007 年頃 )
YUI Library(2008 年頃 )
jQuery/jQuery UI(2008 年~ )
Backbone.js(2013 年頃 )
Riot.js(2016 年頃 )
Angular 1(2014 年~ )
React.js(2014 年~ )
なんぞを一通り使ってみたことはある程度のおっさんです。
3
自己紹介
と、フロントエンドやってる人っぽく書いてみましたが、
本業はディレクション / マネジメントがほとんど。
趣味がてら、 IPA プロジェクトマネージャ、ネットワークスペ
シャリスト、データベーススペシャリスト、情報セキュリティ
スペシャリスト、アプリケーションエンジニアなど。
守備範囲は広めで生きていきたい。
4
自己紹介
なお、このスライドのトンマナは、
スーパーナントカメーカーに影響を受けています。
hico00 氏に表紙をみせたら、神速で
こういうコメントを送ってきましたが、それではない。
(プリンはファミマの「くちどけ贅沢プリン」が好きです。ください。)
5
はじめに
6
はじめに
あけましておめでとうございます。
2017 年もよろしくお願いします。
7
はじめに
ほんだい
8
はじめに
プロダクションの案件で redux-saga を
使ってみたということで、そのお話をしてみます。
9
はじめに
Redux Saga を使うにあたり、
どのような指針で設計をしたか?なぜそのような指針にしたか?その結果、何が見えてきたか?
といった感じの内容です。
10
はじめに
設計思想や考え方の話が多く、抽象的なクダリも多いですが、
ご承知おきください。
あと、 Redux Saga までの前置きの話も長いです。
11
技術要素
12
技術要素
React , Redux , Redux Saga , Apache Cordova , Onsen UI , Sqlite , WebSQL ,
WebAPI(Ajax) , Webpack , Babel(stage-0), ES6 , Generator(ES6) , Promise(ES6),
Gulp, Sass
あたりの技術を使ってます。今日のお話しは、赤字の部分だけ。
13
今日お話しすること
14
今日お話しすること
jQueryReactFLUXRedux
Redux Saga
15
今日お話しすること
順番にいってみよう
16
jQuery
17
jQuery
jQuery はみんな知ってますね?
18
jQuery
画面の状態を変更するときは、DOM を直接操作します。
19
jQuery
20
HTML HTML
HTML の DOM を直接操作する
jQuery
シンプルな構成のサイトで使う分には、全く問題ない。
21
jQuery
静的な HTML のサイトで、
ちょっとアコーディオン。ちょっとインタラクション。
ちょっとタブ切り替え。ちょっと外部 API を呼び出す。
など
22
jQuery
しかし、DOM の変更を多用すると、
どこで何が起きているかわからなくなる。
23
jQuery
外部からデータを取得して、HTML テンプレート定義して、
テンプレートの文字列を置換して、画面に結果の HTML を表示して、
24
jQuery
.append()….appendTo()….addClass()…
.attr()…
… ???
25
jQuery
その間にユーザーが別の操作をしたらどうなる?
外部からデータが取得できなかったらどうなる?
データ呼出しのボタンを連打されたらどうなる?
26
jQuery
DOM 操作するタイミングで、既に DOM の構造が
変化していたらどうなる?
CSS クラス名を付けたり消したりするタイミングが重複したらどうな
る?
27
jQuery
いろんな所でイベントリスナー監視しまくりのコードを
自分が引き継いだら理解できる?
28
jQuery
29
HTML
jQuery
30
HTML HTML
jQuery
31
HTML HTML HTML
jQuery
32
HTML HTML HTML
HTML
jQuery
33
HTML HTML HTML
HTML HTML
元の状態は…???
jQuery
34
※ 出典:山口県周南市徳山動物園のツヨシくん
jQuery
そこで、React のでばん
35
jQuery
React を使うことで、いくつかの課題を解決できます
36
React
37
React
React は、UI を構築するためのライブラリ
38
React
Model, View, Controller のView だけ担当みたいな役割
39
React
Component という単位のパーツを組み合わせて
HTML の DOM 構造を構築する
40
React
Component のクラスの中でJSX という HTML っぽい記法で
DOM の構造を定義できる
41
React
42
HTMLComponent
JSX
React
class HelloMessage extends React.Component { render() { return <div>Hello Jane</div>; }}
ReactDOM.render(<HelloMessage />, mountNode);
43
Component
<div>Hello Jane</div>
HTML
React
HTML の属性と似たようにProps という属性も定義できる。
44
React
45
HTMLComponent
Props
Props は Component が外部から受け取ることができる値オブジェクト指向でいうと setter のようなイメージ
JSX
React
class HelloMessage extends React.Component { render() { return <div>Hello {this.props.name}</div>; }}
ReactDOM.render(<HelloMessage name="Jane" />, mountNode);
46
Component
<div>Hello Jane</div>
HTML
React
Component はProps のほかに、
State とよばれる状態を保持することもできる
47
React
48
HTMLComponent
State
State は、その Component の内部だけで操作できる値オブジェクト指向の private プロパティのようなイメージ
JSX
React
画面の DOM の構造は“Props” と“ State”
の状態によって、決定する
49
React
50
HTMLComponent
State
Props
JSX
React
jQuery の場合だと
51
React
52
HTML HTML
jQuery の場合
HTML の DOM を直接操作する
React
React の場合だと
53
Component
React
54
HTML
React の場合
JSX
Component
Props
React
55
HTML
React の場合
JSX
Component
Props
React
56
HTML
State
React の場合
JSX
Component
Props
React
57
HTML
State
React の場合
JSX
Component
Props
React
58
HTML
State
React の場合
JSX
Component
Props
React
59
HTML
State
React の場合
JSX と State と Props によって、HTML の DOM 構造が決定する
JSX
Component
Props
React
60
HTML
State
React の場合
DOM の構造は、 React が変更を自動的に計算し、差分だけ更新する( Virtual DOM )
JSX
React
Component は部品ごとに細かく分けてネストもできる
61
React
62
HTMLComponent
Component
Component
Component
子の Component には Props で値を渡すことができるオブジェクト指向でいうと別クラスに委譲して引数で値を渡すイメージ
React
63
Component
Component Component
Component Component
Component はツリー上の構造にすることもできて、親から子へのデータは Props で渡していく
React
64
Component
Component Component
Component Component
Callback
Callback
子から親へのデータは、コールバック関数を経由してやり取りする
FLUX
65
FLUX
FLUX は、
アプリケーション構造の
アーキテクチャ
66
FLUX
Hacker Way: Rethinking Web App Development at Facebook
https://www.youtube.com/watch?v=nYkdrAPrdcw
67
FLUX
MVC の場合
※ サーバーサイドの MVC ではなく、
GUI の MVC (Smalltalk MVC) ね。
68
FLUX
構造が複雑になるとスケールしない。
( Model と View のデータフローが双方向で、
コードの影響が予測しにくい)
69
FLUX
この場合も子と親のデータフローが双方向で、
コードの影響が予測しにくい。
70
Component
Component Component
Component Component
Callback
Callback
State更新
FLUX
そこで、 FLUX のでばん
71
FLUX
FLUX の場合
72
FLUX
データフローを単方向にすることで、
コードの影響を予測しやすくする
73
FLUX
74
Action
Dispatcher
Store
View
アプリケーションに必要なデータを保持する領域。データの保持と、データを操作するロジックを持つ。Dispatcher により、メソッドが呼び出される。
Store の状態によって、描画する画面が決定する。
ボタンを押す、といったようなユーザーの操作。
ユーザー操作を受け取って、 Store のメソッドを呼ぶ。( Action を受け取って、 Store に指示を送る。)
FLUX
75
HTMLComponent
State
Props
JSX
React のイメージがこうだとしたら、
FLUX
76
HTMLComponent
State
Props
JSX
State が Component の外に出て、
FLUX
77
HTML
Store
View(Container)
Component
StateProps
JSX
それぞれが Store と View という位置づけに。
FLUX
78
HTMLDispatche
r
View(Container)
Component
Props
JSX
ActionActionAction
StoreStoreStore
State
そして、こんなデータフローに。
FLUX
コードを見てみましょう
79
FLUX
80
HTMLDispatche
r
View(Container)
Component
Props
JSX
ActionActionAction
StoreStoreStore
State
FLUX
import HelloDispatcher from './HelloDispatcher';
const HelloActions = {
changeName(name) { HelloDispatcher.dispatch({ type: ‘CHANGE_NAME’, name, }); }
};
export default HelloActions;
81
HelloAction
ユーザーが Hello ボタンを押したときに呼ばれる。パラメータで name を受け取っている。
Storeへ渡される Action のオブジェクト。type と name を保持している。
FLUX
82
HTMLDispatche
r
View(Container)
Component
Props
JSX
ActionActionAction
StoreStoreStore
State
FLUX
import {Dispatcher} from 'flux';
export default new Dispatcher();
83
HelloDispatcher
Flux が提供してる Dispatcher
FLUX
84
HTMLDispatche
r
View(Container)
Component
Props
JSX
ActionActionAction
StoreStoreStore
State
FLUX
import {ReduceStore} from 'flux/utils';import HelloDispatcher from './HelloDispatcher';
class HelloStore extends ReduceStore {
getInitialState() { return 'Jane'; }
reduce(state, action) { switch (action.type) { case ‘CHANGE_NAME': return action.name; default: return state; } }}
export default new HelloStore(HelloDispatcher);
85
HelloStore
Action を受け取り、ユーザー操作のタイプに応じて、値を返却する。
FLUX
86
HTMLDispatche
r
View(Container)
Component
Props
JSX
ActionActionAction
StoreStoreStore
State
FLUX
import {Container} from 'flux/utils';import HelloStore from './HelloStore';import HelloComponent from './HelloComponent';
class HelloContainer extends Component { static getStores() { return [HelloStore]; } static calculateState(prevState) { return { name: HelloStore.getState(), }; } render() { return <HelloComponent name={this.state.name} />; }}
const AppContainer = Container.create(HelloContainer);ReactDOM.render(<AppContainer />, mountNode);
87
HelloContainer
FLUX
88
HTMLDispatche
r
View(Container)
Component
Props
JSX
ActionActionAction
StoreStoreStore
State
FLUX
import React from 'react';import HelloActions from ‘./HelloActions';
class HelloComponent extends React.Component {
handleChange(event) { HelloActions.changeName(event.target.value); };
render() { return (<div> <div>Hello {this.props.name}</div> <input type=“text” onChange={this.handleChange} /> </div>); }}
export default HelloComponent;
89
HelloComponent
Redux
90
Redux
Redux は、
FLUX と ElmArchitecture に
影響を受けた
ステート管理コンテナ
91
Redux
http://elm-lang.org/(action, state) => state
Elm“updaters”≒ Redux“reducers”このあたりの考え方がおなじ。
92
Redux
Redux は、
FLUX と似ています。
93
Redux
Redux は制約を強めて、
次のような条件をつきます
94
Redux
「 Store は、ひとつだけ」
「 State は、原則、読み取り専用」
「状態の変化は、 Reducer経由で」
95
Redux
Dispatcher という概念もない
96
Redux
97
Action
Reducer
State アプリケーションに必要なデータを保持する領域。
ボタンを押す、といったようなユーザーの操作。
ユーザー操作を受け取って、新しい State を返す。( Action を受け取って、 Store に結果を渡す。)
Redux
98
HTMLDispatche
r
View(Container)
Component
Props
JSX
ActionActionAction
StoreStoreStore
State
これは FLUX のときの図
Redux
99
HTML
Reducer
View(Container)
Component
Props
JSX
ActionActionAction
State
Dispatcher はない。
Store
Redux
100
Reducer
View(Container)
Component
Props
JSX
ActionActionAction
State
Store はひとつだけ。
Redux
101
View(Container)
Component
Props
JSX
ActionActionAction
もうちょっと分解してみると、
Store
Reducer
State
Redux
102
Provider
Component
Props
JSX
ActionActionAction
Container
Store
Reducer
State
こんな感じ
Redux
103
Provider
Component
Props
JSX
ActionActionAction
Container
Store
Reducer
State
Redux
FLUX とだいたい流れは似てますね?
104
Redux
Redux の強み
Middleware
105
Redux
106
Provider
Component
Props
JSX
ActionActionAction
Container
Store
Reducer
State
Redux には、Middleware という仕組みがあります
Redux
107
Provider
ActionActionAction Container
Store
Reducer
State
Component
Props
JSX
Middleware
Redux
Middleware を使うことで
外部 API 呼び出しなどの
非同期処理の取り扱いができる
(副作用とか呼ばれてる)
108
Redux
109
Provider
ActionActionAction Container
Store
Reducer
State
Component
Props
JSX
Middleware外部 API
Redux
Middleware の中のひとつが、
Redux Saga
110
Redux Saga
111
Redux Saga
Action を受け取って
任意のロジックを非同期で処理
112
Redux Saga
113
Provider
Action Action Container
Reducer
State
Component
Props
JSXSaga
外部 API
Action
非同期処理
Redux Saga
Saga から、別の Saga を
呼び出すこともできる
114
Redux Saga
115
Action
Saga
Saga
外部 API
Saga
DB
Saga
外部 API
呼出し方は 2 通り・ Fork: 非同期で呼出し・ Call: 同期的に呼出し
ForkFork Call
Redux Saga
Action を発行したり、
受け取ったりすることもできる
116
Redux Saga
117
Reducer
SagaAction
Saga
Put
Take
Action
Put
Redux Saga
実際のところ、どう使うのか
118
Redux Saga
いろいろな組み合わせ方ができるので
人によって実装がバラバラになる
119
Redux Saga
ある程度のガイドラインを決めたい
120
Redux Saga
いろいろ模索してみた結果
121
Redux Saga
素晴らしい記事と出会う
122
Redux Saga
123https://medium.com/@marcelschulze/using-react-native-with-redux-and-redux-saga-a-new-proposal-ba71f151546f
Redux Saga
Action はすべて Saga を経由する
124
Redux Saga
Action を 2種類で分けて考える
「 System&User Action 」
「 Reducer Action 」
125
Redux Saga
どういうことかというと、
126
Redux Saga
127
Provider
Action Action Container
State
Component
Props
JSXSaga
外部 API
Action Reducer
Redux Saga
128
Provider
Action Action Container
State
Component
Props
JSXSaga
外部 API
Action Reducer
ユーザー操作の Action は直接 Reducerへ渡さない
Redux Saga
129
Provider
Action Container
State
Component
Props
JSXSaga
外部 API
Action Reducer
単一のデータフローを維持(副作用ではなく、主作用として考える)
Redux Saga
130
Provider
Action Container
State
Component
Props
JSXSaga
外部 API
Action Reducer
User Action
Reducer Action
Redux Saga
「 System&User Action 」
ユーザーが操作したアクション
orシステムから発生したアクション
131
Redux Saga
Action の type の命名指針は大事。
「だれが、何を、どうした」
が、わかるような命名に決めた。
e.g. USER_NEWS_ARTICLE_TOUCHEDe.g. SYSTEM_APP_LAUNCHED
132
Redux Saga
「 Reducer Action 」
Reducerへ渡すための
State 更新指示をする Action
133
Redux Saga
こちらも Action の命名指針は大事。
「 Saga が、何を、どうした」
が、わかるような命名に決めた。
e.g. REDUCER_VIEW_NEWS_FETCH_DONE
134
Redux Saga
ほかに、役割ごとにレイヤー化
データフローの流れを決める
135
136
ReduxSaga
Ajax Model
UserAction
UserInterface
DataAccess
DataIntegration
UserEvent
DataStore
StateMachineReducer
Web API XML-RPC Static JSON Database
Ajax
ReduxSaga
Layer Model / with React, Redux, Redux Saga, External API
StateState
Ajax
ReduxContainer
ReduxProvider
ReactComponent
HTTP HTTP HTTP Sqlite/webSQL/localStorage
SystemAction
ReduxSaga
StateEvent
ReducerAction
137
ReduxStore
State
Action
Dispatch
Index.js
Reducer
Action
React
Provider
data
process
component
Action
App
Initial News Product
Action
Dispatch
Action
Dispatch
useroperation
initializecompletion
Saga (Redux Middleware)
Saga(root)
useroperation
take
Saga(thread)
External API
WebAPI
XML-RPC
StaticJSON
fork
fetch / HTTPAjaxcall
Dispatch
Saga(thread)
Ajax
put
Modelcall
fork
fetch / HTTP
select は参照しない。(state(=View 構造 ) に依存するから )( でも通信中状態の判定では必要かも )
put
Internal API
Storage
Action
operation
fetch
Dispatch
Action
凡例
transfered
Redux Saga
という感じの
ガイドラインに落ち着く。
138
まとめ
139
まとめ
React + Redux + Redux Saga学習コストはちょっと高いかも。
慣れてしまえばコードは追いやすい。
メンテも引き継ぎもしやすい。
チームでスケールして戦える。
140
まとめ
レイヤー構造やデータフローを常に
意識しながら設計する必要がある。
設計の難易度はちょっと高めかも。
小さい規模の案件には向かないかも。
長期メンテのある案件には向いてそう。
141
Appendix
142
React Fiber
React Fiber に期待したい気持ち( React コアアルゴリズムの再実装)
60FPS 出せたり、アニメーションの実装がしやすくなるといいな…
https://github.com/acdlite/react-fiber-architecture
(ちなみに、 React 16 から Fiber がデフォルトになるみたい)
143
React Fiber
Andrew Clark: What's Next for React — ReactNext 2016
https://www.youtube.com/watch?v=aV1271hd9ew
144
React Fiber
POSTD のこの記事もよかったです
http://postd.cc/react-fiber-architecture/
145
FLUX Standard Action
Action のデータ構造の標準
https://github.com/acdlite/flux-standard-action
146
An action MUST
- be a plain JavaScript object.- have a type property.
An action MAY
- have an error property.- have a payload property.- have a meta property.
FLUX Standard Action
サンプル
147
{ type: 'ADD_TODO', payload: { text: 'Do something.' }}
FLUX Standard Action
ガイドラインに従うことで、コードのクオリティが均一になるので、積極的に合わせていきましょう。
148
おしまい
149
おしまい
ご清聴ありがとうございました。
150
おしまい
151
Recommended