331 Views
September 14, 16
スライド概要
2016/9/14の勉強会にて発表された資料です。
SCRIPTY#6 ~フロントエンド紳士・淑女のための勉強会~
http://scripty.connpass.com/event/38935/
2023年10月からSpeaker Deckに移行しました。最新情報はこちらをご覧ください。 https://speakerdeck.com/lycorptech_jp
ReactとImmutable.jsで 関数型を体験して思ったこと ヤフー株式会社 メディア・マーケティングソリューションズグループ マーケティングソリューションズカンパニー プロモーション広告開発本部 マーケッターPF開発部 UIエンジニアリング 岡本 和昭 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を 導入した場合のメリットを知る
パフォーマンス改善での活用
パフォーマンス改善での活用 参考) https://facebook.github.io/react/docs/advanced-performance-ja-JP.html ✓ Reactでのパフォーマンス改善と言えば、 shouldComponentUpdate ✓ propsとstateの変更の際に、 再描画判定の実行可否を決定 ✓ 下記のような単純な構造の比較は容易
ネストした場合の対処法 ✓ 先ほどの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を利用した場合 ✓ Immutableは操作の結果が必ず新しい状態を 返すので、直感的なコードになる (階層が深い場合は先ほどのsetIn()でもOK) ✓ ReduxなどのStoreオブジェクトの操作も 同様にシンプルになる 参考) https://github.com/facebook/immutable-js/wiki/Immutable-as-React-state
Reduxでの Record()を利用した モデルの導入
Reduxでのモデルの導入 ✓ Reduxを導入した際に、ロジックが Action, Store, Component のどこかに入り 肥大化するのを解決できる ✓ Immutable.Record() でデータのモデル、 それを継承したクラスでデータを操作する メソッドを定義するとロジックを押しこむ 事が可能になり、肥大化が防げそう
モデルを利用しない場合 編集開始 todoリスト Store操作 の例 (Reducer) 変更保存
モデルを利用しない場合 ✓ データのインデックスを参照し、 対象データを変更する冗長なコードが増える ✓ このようなコードをReducer、Actionなど どこかが必ず持つ運命になっていた
モデルを利用する場合 (モデル本体) ✓ todo自身の状態を 変更する操作は モデル側で定義 編集開始 ✓ 右のedit() と save() の操作の変更の 変更保存 結果をそのまま同じ actionに渡せる(後述)
モデルを利用する場合 (アクション) ✓ 下記の2つのアクションは、変更操作を 前ページのモデル側の別々のメソッドで行い、 その結果を同じアクションに渡している 編集開始 変更保存 ※実際にはイベントハンドラ経由でこれらのコードが呼ばれる
モデルを利用する場合 (Reducer) ✓ モデル側にロジックを移動したので、 アクションが統合されReducerの記述が簡潔に ※前ページのchangeTodoアクションを受け取るReducerのコード例 ✓ 削除など配列本体への操作も、Immutableの おかげで簡潔に(下記の操作はクラス側では行えない)
モデルの利用 ✓ モデルの利用については下記の記事が 参考になりました 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 ! ご静聴ありがとうございました こんな他、こんなメリットもあるよ! などありましたら是非共有お願いします!