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

148 Views

September 14, 16

スライド概要

2016/9/14の勉強会にて発表された資料です。

SCRIPTY#6 ~フロントエンド紳士・淑女のための勉強会~
http://scripty.connpass.com/event/38935/

profile-image

2023年10月からSpeaker Deckに移行しました。最新情報はこちらをご覧ください。 https://speakerdeck.com/lycorptech_jp

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

関連スライド

各ページのテキスト
1.

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

2.

ちょっと自己紹介 岡本 和昭 所属:ヤフー株式会社 職種:フロントエンドエンジニア ✓ 主に広告管理ツールのフロントエンドを開発 ✓ 現在の業務はほぼ「React + Redux」 ✓ Immutable.jsはまだ業務で導入していない

3.

今回の目的 1. JavaScriptにおける関数型のポイントを知る 2. 関数型を後押しするImmutable.jsの概要を知る 3. ReactにImmutable.jsを導入した場合の メリットを知る こんなメリットもあるよ!とかのご意見を ハッシュタグにどんどん投稿してください!

4.

今日やらないこと ✓ 関数型への深い知識、JS以外の関数型言語 ( Lisp, Scala, Clojure ... ) ✓ 高階関数・カリー化・クロージャなどの ワードについて ※JavaScriptで関数型が学べる本もあります https://www.oreilly.co.jp/books/9784873116600/

5.

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

6.

本日のための関数型のポイント (関数型詳しい方、本当ざっくりですみません。) ✓ 関数 → データ → 関数 → データと処理する設計 ✓ 副作用がない(外の状態への依存や変更がない) ✓ 呼び出し元に依存しない ✓ 必ず新しい値を返す(重要) JSを普通に書いてて、これらを守るのは困難

7.

簡単な例 ✓ Good ✓ Bad • 外部の変数に依存し、変更している • 値を返却していない

8.

参照透過性 (が保たれている) 状態とは ✓ 先ほどの性質がが保証された関数のこと ✓ このような関数は、引数が同じであれば 結果は必ず同じになる ✓ 関数の役割・責任・影響範囲が明確であり、 テストもしやすい

9.

オブジェクト指向との比較 ✓ オブジェクト指向はデータとそれに対する 操作をひとつにまとめ、クラスとして定義 ✓ クラスのメソッドの責務や依存も様々 ✓ JavaScriptはES6やTypeScriptにより、 オブジェクト志向色が強まった印象... 「オブジェクト指向 vs 関数型」戦争の勃発

10.

JavaScriptでの関数型所感 ✓ 関数型用に設計された言語と比べると、 関数型を実装するのは難しそう ✓ 関数型言語としての機能は備わっているが、 一方で破壊的変更も簡単に出来てしまう 関数型を後押ししてくれるライブラリの登場

11.

関数型を後押しするライブラリ ✓ underscore(Backboneが依存) ✓ lodash(豊富なメソッド) ✓ Immutable(Facebook製・Reactが推奨)

12.

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

13.

Immutable.js 概要 ✓ Immutable = 不変 ✓ 関数型の考えに強くインスパイアされている ✓ コレクションへの変更は必ず新しいものを 返却し、元のコレクションは変更されない ✓ 遅延評価をサポート( Seq ) (出力タイミングなど結果が必要な時に評価)

14.

Immutable.js 入門 ✓ List (配列に相当)

15.

Immutable.js 入門 ✓ Map(オブジェクトに相当)

16.

Immutable.js 入門 ✓ プレーンなJavaScriptだと、本来は同じ結果 ✓ Immutableで作成したオブジェクトは 不変であり、更新時は必ず新しいものを返す ✓ オブジェクトや配列に必要な 操作はひととおり揃っている ✓ fromJS(), toJS()を利用すればプレーンな JSオブジェクトとの切り替えも可能

17.

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

18.

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

19.

パフォーマンス改善での活用 参考) https://facebook.github.io/react/docs/advanced-performance-ja-JP.html ✓ Reactでのパフォーマンス改善と言えば、 shouldComponentUpdate ✓ propsとstateの変更の際に、 再描画判定の実行可否を決定 ✓ 下記のような単純な構造の比較は容易

20.

ネストした場合の対処法 ✓ 先ほどのvalueの構造がネストすると、 中身の値を含めたディープな比較が出来ない ✓ キーを指定すれば良いが、変更時の修正など メンテが必要になり、バグの温床になる

21.

Immutable.jsを活用した解決法 ✓ ネストしたデータはプレーンな オブジェクトでなく、Map()やList()で定義 ✓ これで正しい判定が可能( is()を使って比較 )

22.

注意点 ✓ MapやList内で更にネストした場合、 それらもMapやListにしないとshallow(浅い) な比較になってしまい正しく判定できない ✓ APIから階層の深いJSONをまるごともらって Storeなどに突っ込む場合はfromJS()を 使った方が楽そう 参考) https://github.com/facebook/immutable-js/wiki/ Converting-from-JS-objects#converting-nested-data

23.

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

24.

ネストされたデータの操作が便利 ✓ Reactとは直接関係ないが、jsで存在しない キーの中身を参照しようとするとエラーになる ✓ ImmutableのsetIn(), getIn()は深い階層の データ変更や参照を安全に行える ✓ 変更後は必ず新しいデータを返却する

25.

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

26.

こんな時に便利 ✓ キーの存在チェックをするコードが不要 ✓ Stateなどのオブジェクトの部分変更時に Object.assignなどを利用したマージが不要 → この後詳しく

27.

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

28.

Stateの操作が便利 ✓ stateはsetStateでキーを指定して更新する ✓ stateの中身がネストした場合、更新時には マージする冗長なコードが増えがちになる ✓ 下記のようなStateの場合を考えてみる

29.

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

30.

Immutable.jsを利用した場合 ✓ Immutableは操作の結果が必ず新しい状態を 返すので、直感的なコードになる (階層が深い場合は先ほどのsetIn()でもOK) ✓ ReduxなどのStoreオブジェクトの操作も 同様にシンプルになる 参考) https://github.com/facebook/immutable-js/wiki/Immutable-as-React-state

31.

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

32.

Reduxでのモデルの導入 ✓ Reduxを導入した際に、ロジックが Action, Store, Component のどこかに入り 肥大化するのを解決できる ✓ Immutable.Record() でデータのモデル、 それを継承したクラスでデータを操作する メソッドを定義するとロジックを押しこむ 事が可能になり、肥大化が防げそう

33.

モデルを利用しない場合 編集開始 todoリスト Store操作 の例 (Reducer) 変更保存

34.

モデルを利用しない場合 ✓ データのインデックスを参照し、 対象データを変更する冗長なコードが増える ✓ このようなコードをReducer、Actionなど どこかが必ず持つ運命になっていた

35.

モデルを利用する場合 (モデル本体) ✓ todo自身の状態を 変更する操作は モデル側で定義 編集開始 ✓ 右のedit() と save() の操作の変更の 変更保存 結果をそのまま同じ actionに渡せる(後述)

36.

モデルを利用する場合 (アクション) ✓ 下記の2つのアクションは、変更操作を 前ページのモデル側の別々のメソッドで行い、 その結果を同じアクションに渡している 編集開始 変更保存 ※実際にはイベントハンドラ経由でこれらのコードが呼ばれる

37.

モデルを利用する場合 (Reducer) ✓ モデル側にロジックを移動したので、 アクションが統合されReducerの記述が簡潔に ※前ページのchangeTodoアクションを受け取るReducerのコード例 ✓ 削除など配列本体への操作も、Immutableの おかげで簡潔に(下記の操作はクラス側では行えない)

38.

モデルの利用 ✓ モデルの利用については下記の記事が 参考になりました 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

39.

React + Immutableの所感 ✓ 関数型のメリットをうまく活かして、 コードの量や見通しを改善できそう ✓ 途中から全て書き換えるのはコストが 大きそうなので、早いうちに導入すべき ✓ 部分的にImmutableにしてしまうと プレーンなjsとの区別がつきにくそう (混在する場合は何か工夫が必要そう)

40.

Thank You ! ご静聴ありがとうございました こんな他、こんなメリットもあるよ! などありましたら是非共有お願いします!