ReactとImmutable.jsで関数型を体験してみて思ったこと #scripty06
-
Upload
yahoo -
Category
Technology
-
view
695 -
download
0
Transcript of ReactとImmutable.jsで関数型を体験してみて思ったこと #scripty06
メディア・マーケティングソリューションズグループマーケティングソリューションズカンパニー
プロモーション広告開発本部 マーケッターPF開発部UIエンジニアリング
岡本 和昭
ReactとImmutable.jsで関数型を体験して思ったこと
2016/09/14 SCRIPTY#6
ヤフー株式会社
ちょっと自己紹介
岡本 和昭
主に広告管理ツールのフロントエンドを開発
現在の業務はほぼ「React + Redux」
Immutable.jsはまだ業務で導入していない
所属:ヤフー株式会社
職種:フロントエンドエンジニア
今回の目的
1. JavaScriptにおける関数型のポイントを知る
2. 関数型を後押しするImmutable.jsの概要を知る
3. ReactにImmutable.jsを導入した場合のメリットを知る
こんなメリットもあるよ!とかのご意見を
ハッシュタグにどんどん投稿してください!
今日やらないこと
関数型への深い知識、JS以外の関数型言語( Lisp, Scala, Clojure ... )
高階関数・カリー化・クロージャなどのワードについて
※JavaScriptで関数型が学べる本もありますhttps://www.oreilly.co.jp/books/9784873116600/
JavaScriptにおける
関数型のポイントを知る
関数→データ→関数→データと処理する設計
副作用がない(外の状態への依存や変更がない)
呼び出し元に依存しない
必ず新しい値を返す(重要)
JSを普通に書いてて、これらを守るのは困難
本日のための関数型のポイント
(関数型詳しい方、本当ざっくりですみません。)
簡単な例
Good
Bad
• 外部の変数に依存し、変更している
• 値を返却していない
参照透過性 (が保たれている) 状態とは
先ほどの性質がが保証された関数のこと
このような関数は、引数が同じであれば結果は必ず同じになる
関数の役割・責任・影響範囲が明確であり、テストもしやすい
オブジェクト指向との比較
オブジェクト指向はデータとそれに対する操作をひとつにまとめ、クラスとして定義
クラスのメソッドの責務や依存も様々
JavaScriptはES6やTypeScriptにより、オブジェクト志向色が強まった印象...
「オブジェクト指向 vs 関数型」戦争の勃発
JavaScriptでの関数型所感
関数型用に設計された言語と比べると、関数型を実装するのは難しそう
関数型言語としての機能は備わっているが、一方で破壊的変更も簡単に出来てしまう
関数型を後押ししてくれるライブラリの登場
関数型を後押しするライブラリ
underscore(Backboneが依存)
lodash(豊富なメソッド)
Immutable(Facebook製・Reactが推奨)
関数型を後押しするImmutable.jsの概要を知る
Immutable.js概要
Immutable = 不変
関数型の考えに強くインスパイアされている
コレクションへの変更は必ず新しいものを返却し、元のコレクションは変更されない
遅延評価をサポート( Seq )(出力タイミングなど結果が必要な時に評価)
Immutable.js入門
List (配列に相当)
Immutable.js入門
Map(オブジェクトに相当)
Immutable.js入門
プレーンなJavaScriptだと、本来は同じ結果
Immutableで作成したオブジェクトは不変であり、更新時は必ず新しいものを返す
オブジェクトや配列に必要な操作はひととおり揃っている
fromJS(), toJS()を利用すればプレーンなJSオブジェクトとの切り替えも可能
ReactにImmutable.jsを導入した場合のメリットを知る
パフォーマンス改善での活用
パフォーマンス改善での活用
Reactでのパフォーマンス改善と言えば、shouldComponentUpdate
propsとstateの変更の際に、再描画判定の実行可否を決定
下記のような単純な構造の比較は容易
参考) https://facebook.github.io/react/docs/advanced-performance-ja-JP.html
ネストした場合の対処法
先ほどのvalueの構造がネストすると、中身の値を含めたディープな比較が出来ない
キーを指定すれば良いが、変更時の修正などメンテが必要になり、バグの温床になる
Immutable.jsを活用した解決法
ネストしたデータはプレーンなオブジェクトでなく、Map()やList()で定義
これで正しい判定が可能 ( is()を使って比較 )
注意点
MapやList内で更にネストした場合、それらもMapやListにしないとshallow(浅い)な比較になってしまい正しく判定できない
APIから階層の深いJSONをまるごともらってStoreなどに突っ込む場合はfromJS()を使った方が楽そう
参考) https://github.com/facebook/immutable-js/wiki/Converting-from-JS-objects#converting-nested-data
ネストされたデータの安全な操作
ネストされたデータの操作が便利
Reactとは直接関係ないが、jsで存在しないキーの中身を参照しようとするとエラーになる
ImmutableのsetIn(), getIn()は深い階層のデータ変更や参照を安全に行える
変更後は必ず新しいデータを返却する
ネストされたデータへの操作例
こんな時に便利
キーの存在チェックをするコードが不要
Stateなどのオブジェクトの部分変更時にObject.assignなどを利用したマージが不要→この後詳しく
StateやStoreオブジェクトの操作が便利
Stateの操作が便利
stateはsetStateでキーを指定して更新する
stateの中身がネストした場合、更新時にはマージする冗長なコードが増えがちになる
下記のようなStateの場合を考えてみる
従来のStateの操作
キーを指定し、新しいStateを設定するので下記のような現状維持部分とマージするコードが必要になる
Immutable.jsを利用した場合
参考) https://github.com/facebook/immutable-js/wiki/Immutable-as-React-state
Immutableは操作の結果が必ず新しい状態を返すので、直感的なコードになる(階層が深い場合は先ほどのsetIn()でもOK)
ReduxなどのStoreオブジェクトの操作も同様にシンプルになる
ReduxでのRecord()を利用したモデルの導入
Reduxでのモデルの導入
Reduxを導入した際に、ロジックがAction, Store, Component のどこかに入り肥大化するのを解決できる
Immutable.Record() でデータのモデル、それを継承したクラスでデータを操作するメソッドを定義するとロジックを押しこむ事が可能になり、肥大化が防げそう
モデルを利用しない場合
todoリストStore操作の例(Reducer)
編集開始
変更保存
モデルを利用しない場合
データのインデックスを参照し、対象データを変更する冗長なコードが増える
このようなコードをReducer、Actionなどどこかが必ず持つ運命になっていた
モデルを利用する場合 (モデル本体)
todo自身の状態を変更する操作はモデル側で定義
右のedit()と save()の操作の変更の結果をそのまま同じactionに渡せる(後述)
編集開始
変更保存
モデルを利用する場合 (アクション)
下記の2つのアクションは、変更操作を前ページのモデル側の別々のメソッドで行い、その結果を同じアクションに渡している
※実際にはイベントハンドラ経由でこれらのコードが呼ばれる
編集開始
変更保存
モデルを利用する場合 (Reducer)
モデル側にロジックを移動したので、アクションが統合されReducerの記述が簡潔に
削除など配列本体への操作も、Immutableのおかげで簡潔に(下記の操作はクラス側では行えない)
※前ページのchangeTodoアクションを受け取るReducerのコード例
モデルの利用
モデルの利用については下記の記事が参考になりました
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
React + Immutableの所感
関数型のメリットをうまく活かして、コードの量や見通しを改善できそう
途中から全て書き換えるのはコストが大きそうなので、早いうちに導入すべき
部分的にImmutableにしてしまうとプレーンなjsとの区別がつきにくそう(混在する場合は何か工夫が必要そう)
Thank You !ご静聴ありがとうございました
こんな他、こんなメリットもあるよ!
などありましたら是非共有お願いします!