reactとimmutable.jsで関数型を体験してみて思ったこと #scripty06

40
メディア・マーケティングソリューションズグループ マーケティングソリューションズカンパニー プロモーション広告開発本部 マーケッターPF開発部 UIエンジニアリング 岡本 和昭 ReactとImmutable.jsで 関数型を体験して思ったこと 2016/09/14 SCRIPTY#6 ヤフー株式会社

Upload: yahoo

Post on 09-Jan-2017

693 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: ReactとImmutable.jsで関数型を体験してみて思ったこと #scripty06

メディア・マーケティングソリューションズグループマーケティングソリューションズカンパニー

プロモーション広告開発本部 マーケッターPF開発部UIエンジニアリング

岡本 和昭

ReactとImmutable.jsで関数型を体験して思ったこと

2016/09/14 SCRIPTY#6

ヤフー株式会社

Page 2: ReactとImmutable.jsで関数型を体験してみて思ったこと #scripty06

ちょっと自己紹介

岡本 和昭

主に広告管理ツールのフロントエンドを開発

現在の業務はほぼ「React + Redux」

Immutable.jsはまだ業務で導入していない

所属:ヤフー株式会社

職種:フロントエンドエンジニア

Page 3: ReactとImmutable.jsで関数型を体験してみて思ったこと #scripty06

今回の目的

1. JavaScriptにおける関数型のポイントを知る

2. 関数型を後押しするImmutable.jsの概要を知る

3. ReactにImmutable.jsを導入した場合のメリットを知る

こんなメリットもあるよ!とかのご意見を

ハッシュタグにどんどん投稿してください!

Page 4: ReactとImmutable.jsで関数型を体験してみて思ったこと #scripty06

今日やらないこと

関数型への深い知識、JS以外の関数型言語( Lisp, Scala, Clojure ... )

高階関数・カリー化・クロージャなどのワードについて

※JavaScriptで関数型が学べる本もありますhttps://www.oreilly.co.jp/books/9784873116600/

Page 5: ReactとImmutable.jsで関数型を体験してみて思ったこと #scripty06

JavaScriptにおける

関数型のポイントを知る

Page 6: ReactとImmutable.jsで関数型を体験してみて思ったこと #scripty06

関数→データ→関数→データと処理する設計

副作用がない(外の状態への依存や変更がない)

呼び出し元に依存しない

必ず新しい値を返す(重要)

JSを普通に書いてて、これらを守るのは困難

本日のための関数型のポイント

(関数型詳しい方、本当ざっくりですみません。)

Page 7: ReactとImmutable.jsで関数型を体験してみて思ったこと #scripty06

簡単な例

Good

Bad

• 外部の変数に依存し、変更している

• 値を返却していない

Page 8: ReactとImmutable.jsで関数型を体験してみて思ったこと #scripty06

参照透過性 (が保たれている) 状態とは

先ほどの性質がが保証された関数のこと

このような関数は、引数が同じであれば結果は必ず同じになる

関数の役割・責任・影響範囲が明確であり、テストもしやすい

Page 9: ReactとImmutable.jsで関数型を体験してみて思ったこと #scripty06

オブジェクト指向との比較

オブジェクト指向はデータとそれに対する操作をひとつにまとめ、クラスとして定義

クラスのメソッドの責務や依存も様々

JavaScriptはES6やTypeScriptにより、オブジェクト志向色が強まった印象...

「オブジェクト指向 vs 関数型」戦争の勃発

Page 10: ReactとImmutable.jsで関数型を体験してみて思ったこと #scripty06

JavaScriptでの関数型所感

関数型用に設計された言語と比べると、関数型を実装するのは難しそう

関数型言語としての機能は備わっているが、一方で破壊的変更も簡単に出来てしまう

関数型を後押ししてくれるライブラリの登場

Page 11: ReactとImmutable.jsで関数型を体験してみて思ったこと #scripty06

関数型を後押しするライブラリ

underscore(Backboneが依存)

lodash(豊富なメソッド)

Immutable(Facebook製・Reactが推奨)

Page 12: ReactとImmutable.jsで関数型を体験してみて思ったこと #scripty06

関数型を後押しするImmutable.jsの概要を知る

Page 13: ReactとImmutable.jsで関数型を体験してみて思ったこと #scripty06

Immutable.js概要

Immutable = 不変

関数型の考えに強くインスパイアされている

コレクションへの変更は必ず新しいものを返却し、元のコレクションは変更されない

遅延評価をサポート( Seq )(出力タイミングなど結果が必要な時に評価)

Page 14: ReactとImmutable.jsで関数型を体験してみて思ったこと #scripty06

Immutable.js入門

List (配列に相当)

Page 15: ReactとImmutable.jsで関数型を体験してみて思ったこと #scripty06

Immutable.js入門

Map(オブジェクトに相当)

Page 16: ReactとImmutable.jsで関数型を体験してみて思ったこと #scripty06

Immutable.js入門

プレーンなJavaScriptだと、本来は同じ結果

Immutableで作成したオブジェクトは不変であり、更新時は必ず新しいものを返す

オブジェクトや配列に必要な操作はひととおり揃っている

fromJS(), toJS()を利用すればプレーンなJSオブジェクトとの切り替えも可能

Page 17: ReactとImmutable.jsで関数型を体験してみて思ったこと #scripty06

ReactにImmutable.jsを導入した場合のメリットを知る

Page 18: ReactとImmutable.jsで関数型を体験してみて思ったこと #scripty06

パフォーマンス改善での活用

Page 19: ReactとImmutable.jsで関数型を体験してみて思ったこと #scripty06

パフォーマンス改善での活用

Reactでのパフォーマンス改善と言えば、shouldComponentUpdate

propsとstateの変更の際に、再描画判定の実行可否を決定

下記のような単純な構造の比較は容易

参考) https://facebook.github.io/react/docs/advanced-performance-ja-JP.html

Page 20: ReactとImmutable.jsで関数型を体験してみて思ったこと #scripty06

ネストした場合の対処法

先ほどのvalueの構造がネストすると、中身の値を含めたディープな比較が出来ない

キーを指定すれば良いが、変更時の修正などメンテが必要になり、バグの温床になる

Page 21: ReactとImmutable.jsで関数型を体験してみて思ったこと #scripty06

Immutable.jsを活用した解決法

ネストしたデータはプレーンなオブジェクトでなく、Map()やList()で定義

これで正しい判定が可能 ( is()を使って比較 )

Page 22: ReactとImmutable.jsで関数型を体験してみて思ったこと #scripty06

注意点

MapやList内で更にネストした場合、それらもMapやListにしないとshallow(浅い)な比較になってしまい正しく判定できない

APIから階層の深いJSONをまるごともらってStoreなどに突っ込む場合はfromJS()を使った方が楽そう

参考) https://github.com/facebook/immutable-js/wiki/Converting-from-JS-objects#converting-nested-data

Page 23: ReactとImmutable.jsで関数型を体験してみて思ったこと #scripty06

ネストされたデータの安全な操作

Page 24: ReactとImmutable.jsで関数型を体験してみて思ったこと #scripty06

ネストされたデータの操作が便利

Reactとは直接関係ないが、jsで存在しないキーの中身を参照しようとするとエラーになる

ImmutableのsetIn(), getIn()は深い階層のデータ変更や参照を安全に行える

変更後は必ず新しいデータを返却する

Page 25: ReactとImmutable.jsで関数型を体験してみて思ったこと #scripty06

ネストされたデータへの操作例

Page 26: ReactとImmutable.jsで関数型を体験してみて思ったこと #scripty06

こんな時に便利

キーの存在チェックをするコードが不要

Stateなどのオブジェクトの部分変更時にObject.assignなどを利用したマージが不要→この後詳しく

Page 27: ReactとImmutable.jsで関数型を体験してみて思ったこと #scripty06

StateやStoreオブジェクトの操作が便利

Page 28: ReactとImmutable.jsで関数型を体験してみて思ったこと #scripty06

Stateの操作が便利

stateはsetStateでキーを指定して更新する

stateの中身がネストした場合、更新時にはマージする冗長なコードが増えがちになる

下記のようなStateの場合を考えてみる

Page 29: ReactとImmutable.jsで関数型を体験してみて思ったこと #scripty06

従来のStateの操作

キーを指定し、新しいStateを設定するので下記のような現状維持部分とマージするコードが必要になる

Page 30: ReactとImmutable.jsで関数型を体験してみて思ったこと #scripty06

Immutable.jsを利用した場合

参考) https://github.com/facebook/immutable-js/wiki/Immutable-as-React-state

Immutableは操作の結果が必ず新しい状態を返すので、直感的なコードになる(階層が深い場合は先ほどのsetIn()でもOK)

ReduxなどのStoreオブジェクトの操作も同様にシンプルになる

Page 31: ReactとImmutable.jsで関数型を体験してみて思ったこと #scripty06

ReduxでのRecord()を利用したモデルの導入

Page 32: ReactとImmutable.jsで関数型を体験してみて思ったこと #scripty06

Reduxでのモデルの導入

Reduxを導入した際に、ロジックがAction, Store, Component のどこかに入り肥大化するのを解決できる

Immutable.Record() でデータのモデル、それを継承したクラスでデータを操作するメソッドを定義するとロジックを押しこむ事が可能になり、肥大化が防げそう

Page 33: ReactとImmutable.jsで関数型を体験してみて思ったこと #scripty06

モデルを利用しない場合

todoリストStore操作の例(Reducer)

編集開始

変更保存

Page 34: ReactとImmutable.jsで関数型を体験してみて思ったこと #scripty06

モデルを利用しない場合

データのインデックスを参照し、対象データを変更する冗長なコードが増える

このようなコードをReducer、Actionなどどこかが必ず持つ運命になっていた

Page 35: ReactとImmutable.jsで関数型を体験してみて思ったこと #scripty06

モデルを利用する場合 (モデル本体)

todo自身の状態を変更する操作はモデル側で定義

右のedit()と save()の操作の変更の結果をそのまま同じactionに渡せる(後述)

編集開始

変更保存

Page 36: ReactとImmutable.jsで関数型を体験してみて思ったこと #scripty06

モデルを利用する場合 (アクション)

下記の2つのアクションは、変更操作を前ページのモデル側の別々のメソッドで行い、その結果を同じアクションに渡している

※実際にはイベントハンドラ経由でこれらのコードが呼ばれる

編集開始

変更保存

Page 37: ReactとImmutable.jsで関数型を体験してみて思ったこと #scripty06

モデルを利用する場合 (Reducer)

モデル側にロジックを移動したので、アクションが統合されReducerの記述が簡潔に

削除など配列本体への操作も、Immutableのおかげで簡潔に(下記の操作はクラス側では行えない)

※前ページのchangeTodoアクションを受け取るReducerのコード例

Page 38: ReactとImmutable.jsで関数型を体験してみて思ったこと #scripty06

モデルの利用

モデルの利用については下記の記事が参考になりました

React使い必見! Immutable.jsでReactはもっと良くなるhttps://www.wantedly.com/companies/wantedly/post_articles/28935

How to use Immutable.js Records with React and Redux https://medium.com/azendoo-team/immutable-record-react-redux-99f389ed676

Page 39: ReactとImmutable.jsで関数型を体験してみて思ったこと #scripty06

React + Immutableの所感

関数型のメリットをうまく活かして、コードの量や見通しを改善できそう

途中から全て書き換えるのはコストが大きそうなので、早いうちに導入すべき

部分的にImmutableにしてしまうとプレーンなjsとの区別がつきにくそう(混在する場合は何か工夫が必要そう)

Page 40: ReactとImmutable.jsで関数型を体験してみて思ったこと #scripty06

Thank You !ご静聴ありがとうございました

こんな他、こんなメリットもあるよ!

などありましたら是非共有お願いします!