React + FLUX + Redux + Redux Saga のお話

Preview:

Citation preview

React + FLUX + Redux + ReduxSagaのお話

2017/03/23(木)

ARCANA Meetup #23

よしだしんいちろう

自己紹介

name: “よしだ しんいちろう”

age: 33

worksAt: “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.js(2014年~)

React.js(2014年~)

Vue.js(2016年~)

3

自己紹介

と、フロントエンドやってる人っぽく書いてみましたが、

本業はディレクション/マネジメントです。

むかしはCOBOLとかJavaとかCとかRubyとかやってました。

いまはPHPとJavaScriptがほとんどです。

AWSでインフラ作ったりするときもあります。

4

はじめに

5

はじめに

社内勉強会 #21でお話しした『実践 Redux Saga』

というスライドの圧縮版です。

ご了承を…!

6

はじめに

ほんだい

7

はじめに

プロダクションの案件でRedux Sagaを

使ってみたということで、そのお話をしてみます。

8

はじめに

Redux Sagaを使うにあたり、

どのような指針で設計をしたか?なぜそのような指針にしたか?その結果、何が見えてきたか?

といった感じの内容です。

9

はじめに

設計思想や考え方の話が多く、抽象的なクダリも多いですが、ご承知おきください。

あと、Redux Sagaまでの前置きの話も長いです。

10

技術要素

11

技術要素

React , Redux , Redux Saga , Apache

Cordova , Onsen UI , Sqlite , WebSQL ,

WebAPI(Ajax) , Webpack , Babel(stage-0),

ES6 , Generator(ES6) , Promise(ES6),

Gulp, Sass

あたりの技術を使ってます。今日のお話しは、赤字の部分だけ。

12

今日お話しすること

13

今日お話しすること

jQuery

React

FLUX

Redux

Redux Saga

14

今日お話しすること

順番にいってみよう

15

jQuery

16

jQuery

jQueryはみんな知ってますね?

17

jQuery

画面の状態を変更するときは、DOMを直接操作します。

18

jQuery

19

HTML HTML

HTMLのDOMを直接操作する

jQuery

シンプルな構成のサイトで使う分には、全く問題ない。

20

jQuery

静的なHTMLのサイトで、

ちょっとアコーディオン。ちょっとインタラクション。ちょっとタブ切り替え。

ちょっと外部APIを呼び出す。

など

21

jQuery

しかし、DOMの変更を多用すると、どこで何が起きているかわからなくなる。

22

jQuery

外部からデータを取得して、HTMLテンプレート定義して、

テンプレートの文字列を置換して、画面に結果のHTMLを表示して、

23

jQuery

.append()…

.appendTo()…

.addClass()…

.attr()…

…???

24

jQuery

その間にユーザーが別の操作をしたらどうなる?

外部からデータが取得できなかったらどうなる?

データ呼出しのボタンを連打されたらどうなる?

25

jQuery

DOM操作するタイミングで、既にDOMの構造が

変化していたらどうなる?

CSSクラス名を付けたり消したりするタイミングが重複したらどうなる?

26

jQuery

いろんな所でイベントリスナー監視しまくりのコードを

自分が引き継いだら理解できる?

27

jQuery

28

HTML

jQuery

29

HTML HTML

jQuery

30

HTML HTML HTML

jQuery

31

HTML HTML HTML

HTML

jQuery

32

HTML HTML HTML

HTML HTML

元の状態は…

???

jQuery

33

※出典:山口県周南市徳山動物園のツヨシくん

jQuery

そこで、Reactのでばん

34

jQuery

Reactを使うことで、いくつかの課題を解決できます

35

React

36

React

Reactは、UIを構築するためのライブラリ

37

React

Model, View, ControllerのViewだけ担当みたいな役割

38

React

Componentという単位のパーツを組み合わせて

HTMLのDOM構造を構築する

39

React

Componentのクラスの中でJSXというHTMLっぽい記法で

DOMの構造を定義できる

40

React

41

HTMLComponent

JSX

React

class HelloMessage extends React.Component {render() {return <div>Hello Jane</div>;

}}

ReactDOM.render(<HelloMessage />, mountNode);

42

Component

<div>Hello Jane</div>

HTML

React

HTMLの属性と似たようにPropsという属性も定義できる。

43

React

44

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);

45

Component

<div>Hello Jane</div>

HTML

React

ComponentはPropsのほかに、

Stateとよばれる状態を保持することもできる

46

React

47

HTMLComponent

State

Stateは、そのComponentの内部だけで操作できる値オブジェクト指向のprivateプロパティのようなイメージ

JSX

React

画面のDOMの構造は“Props”と“State”

の状態によって、決定する

48

React

49

HTMLComponent

State

Props

JSX

React

jQueryの場合だと

50

React

51

HTML HTML

jQueryの場合

HTMLのDOMを直接操作する

React

Reactの場合だと

52

Component

React

53

HTML

Reactの場合

JSX

Component

Props

React

54

HTML

Reactの場合

JSX

Component

Props

React

55

HTML

State

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とStateとPropsによって、HTMLのDOM構造が決定する

JSX

Component

Props

React

59

HTML

State

Reactの場合

DOMの構造は、Reactが変更を自動的に計算し、差分だけ更新する(Virtual DOM)

JSX

React

Componentは部品ごとに細かく分けてネストもできる

60

React

61

HTMLComponent

Component

Component

Component

子のComponentにはPropsで値を渡すことができるオブジェクト指向でいうと別クラスに委譲して引数で値を渡すイメージ

React

62

Component

Component Component

Component Component

Componentはツリー上の構造にすることもできて、親から子へのデータはPropsで渡していく

React

63

Component

Component Component

Component Component

Callback

Callback

子から親へのデータは、コールバック関数を経由してやり取りする

FLUX

64

FLUX

FLUXは、

アプリケーション構造の

アーキテクチャ

65

FLUX

Hacker Way: Rethinking Web App Development at Facebook

https://www.youtube.com/watch?v=nYkdrAPrdcw

66

FLUX

MVCの場合

※サーバーサイドのMVCではなく、

GUIのMVC (Smalltalk MVC) ね。

67

FLUX

構造が複雑になるとスケールしない。

(ModelとViewのデータフローが双方向で、

コードの影響が予測しにくい)

68

FLUX

この場合も子と親のデータフローが双方向で、

コードの影響が予測しにくい。

69

Component

Component Component

Component Component

Callback

Callback

State更新

FLUX

そこで、FLUXのでばん

70

FLUX

FLUXの場合

71

FLUX

データフローを単方向にすることで、

コードの影響を予測しやすくする

72

FLUX

73

Action

Dispatcher

Store

View

アプリケーションに必要なデータを保持する領域。データの保持と、データを操作するロジックを持つ。Dispatcherにより、メソッドが呼び出される。

Storeの状態によって、描画する画面が決定する。

ボタンを押す、といったようなユーザーの操作。

ユーザー操作を受け取って、Storeのメソッドを呼ぶ。(Actionを受け取って、Storeに指示を送る。)

FLUX

74

HTMLComponent

State

Props

JSX

Reactのイメージがこうだとしたら、

FLUX

75

HTMLComponent

State

Props

JSX

StateがComponentの外に出て、

FLUX

76

HTML

Store

View(Container)

Component

State

Props

JSX

それぞれがStoreとViewという位置づけに。

FLUX

77

HTMLDispatcher

View(Container)

Component

Props

JSX

ActionActionAction

StoreStoreStore

State

そして、こんなデータフローに。

Redux

78

Redux

Reduxは、

FLUXとElmArchitectureに

影響を受けた

ステート管理コンテナ

79

Redux

http://elm-lang.org/

(action, state) => state

Elm“updaters”≒ Redux“reducers”

このあたりの考え方がおなじ。

80

Redux

Reduxは、

FLUXと似ています。

81

Redux

Reduxは制約を強めて、

次のような条件をつきます

82

Redux

「Storeは、ひとつだけ」

「Stateは、原則、読み取り専用」

「状態の変化は、Reducer経由で」

83

Redux

Dispatcherという概念もない

84

Redux

85

Action

Reducer

State アプリケーションに必要なデータを保持する領域。

ボタンを押す、といったようなユーザーの操作。

ユーザー操作を受け取って、新しいStateを返す。(Actionを受け取って、Storeに結果を渡す。)

Redux

86

HTMLDispatcher

View(Container)

Component

Props

JSX

ActionActionAction

StoreStoreStore

State

これはFLUXのときの図

Redux

87

HTML

Reducer

View(Container)

Component

Props

JSX

ActionActionAction

State

Reduxだとこうなる

Redux

88

HTML

Reducer

View(Container)

Component

Props

JSX

ActionActionAction

State

Reduxには、Dispatcherがない。

Store

Redux

89

Reducer

View(Container)

Component

Props

JSX

ActionActionAction

State

Storeはひとつだけ。

HTML

Store

Redux

90

Reducer

View(Container)

Component

Props

JSX

ActionActionAction

State

ちょっと分解してみます

Redux

91

View(Container)

Component

Props

JSX

ActionActionAction

Componentを外にだして、

Store

Reducer

State

Redux

92

Component

Props

JSX

ActionActionAction

Container

Store

Reducer

State

ViewをContainerとします

Redux

93

Component

Props

JSX

ActionActionAction

Container

Store

Reducer

State

Redux

FLUXとだいたい流れは似てますね?

94

Redux

Reduxの強み

Middleware

95

Redux

96

Component

Props

JSX

ActionActionAction

Container

Store

Reducer

State

Reduxには、Middlewareという仕組みがあります

Redux

97

Container

ActionActionAction

Store

Reducer

State

Component

JSX

ちょっと配置を変えまして、

Redux

98

Container

ActionActionAction

Store

Reducer

State

Component

JSX

Middleware

MiddlewareはStoreのココ

Redux

Middlewareを使うことで

外部API呼び出しなどの

非同期処理の取り扱いができる

(副作用とか呼ばれてる)

99

Redux

100

Container

ActionActionAction

Store

Reducer

State

Component

JSX

Middleware外部API

Redux

Middlewareの中のひとつが、

Redux Saga

101

Redux Saga

102

Redux Saga

Actionを受け取って

任意のロジックを非同期で処理

103

Redux Saga

104

Container

Action Action

Reducer

State

Component

JSXSaga

外部API

Action

非同期処理

Redux Saga

Sagaから、別のSagaを

呼び出すこともできる

105

Redux Saga

106

Action

Saga

Saga

外部API

Saga

DB

Saga

外部API

呼出し方は2通り・Fork:非同期で呼出し・Call:同期的に呼出し

Fork

Fork Call

Redux Saga

Actionを発行したり、

受け取ったりすることもできる

107

Redux Saga

108

Reducer

SagaAction

Saga

Put

Take

Action

Put

Redux Saga

実際のところ、どう使うのか

109

Redux Saga

いろいろな組み合わせ方ができるので

人によって実装がバラバラになる

110

Redux Saga

ある程度のガイドラインを決めたい

111

Redux Saga

いろいろ模索してみた結果

112

Redux Saga

素晴らしい記事と出会う

113

Redux Saga

ActionはすべてSagaを経由する

115

Redux Saga

Actionを2種類で分けて考える

「System&User Action」

「Reducer Action」

116

Redux Saga

どういうことかというと、

117

Redux Saga

118

Container

Action Action

State

Component

JSXSaga

外部API

Action Reducer

Redux Saga

119

Container

Action Action

State

Component

JSXSaga

外部API

Action Reducer

ユーザー操作のActionは直接Reducerへ渡さない

Redux Saga

120

Container

Action

State

Component

JSXSaga

外部API

Action Reducer

単一のデータフローを維持(副作用ではなく、主作用として考える)

Redux Saga

121

Container

Action

State

Component

JSXSaga

外部API

Action Reducer

User Action

Reducer Action

Redux Saga

「System&User Action」

ユーザーが操作したアクション

or

システムから発生したアクション

122

Redux Saga

Actionのtypeの命名指針は大事。

「だれが、何を、どうした」

が、わかるような命名に決めた。

e.g. USER_NEWS_ARTICLE_TOUCHED

e.g. SYSTEM_APP_LAUNCHED

123

Redux Saga

「Reducer Action」

Reducerへ渡すための

State更新指示をするAction

124

Redux Saga

こちらもActionの命名指針は大事。

「Sagaが、何を、どうした」

が、わかるような命名に決めた。

接頭辞は REDUCER_とした。

e.g. REDUCER_VIEW_NEWS_FETCH_DONE

125

Redux Saga

ほかに、役割ごとにレイヤー化

データフローの流れを決める

126

127

ReduxSaga

Ajax Model

UserAction

UserInterface

DataAccess

DataIntegration

UserEvent

DataStore

StateMachine

Reducer

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

128

Redux

Store

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

という感じの

ガイドラインに落ち着く。

129

まとめ

130

まとめ

React + Redux + Redux Saga

学習コストはちょっと高いかも。

慣れてしまえばコードは追いやすい。

メンテも引き継ぎもしやすい。

チームでスケールして戦える。

131

まとめ

レイヤー構造やデータフローを常に

意識しながら設計する必要がある。

設計の難易度はちょっと高めかも。

小さい規模の案件には向かないかも。

長期メンテのある案件には向いてそう。

132

Appendix

133

React Fiber

React Fiberに期待したい気持ち(Reactコアアルゴリズムの再実装)

60FPS出せたり、アニメーションの実装がしやすくなるといいな…

https://github.com/acdlite/react-fiber-architecture

134

React Fiber

Andrew Clark: What's Next for React — ReactNext 2016

https://www.youtube.com/watch?v=aV1271hd9ew

135

React Fiber

POSTDのこの記事もよかったです

http://postd.cc/react-fiber-architecture/

136

React Fiber

https://github.com/facebook/react/issues/8854

(ちなみに、React 16からFiberがデフォ搭載になるみたい)

137

FLUX Standard Action

Actionのデータ構造の標準

https://github.com/acdlite/flux-standard-action

138

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

サンプル

139

{type: 'ADD_TODO',payload: {text: 'Do something.'

}}

FLUX Standard Action

ガイドラインに従うことで、コードのクオリティが均一になるので、積極的に合わせていきましょう。

140

おしまい

141

おしまい

ご清聴ありがとうございました。

142

おしまい

143