Slide 1

Slide 1 text

Reactについての 良くある問答 2017/05/10 株式会社マネーフォワード UIテクノロジー部 石井 光次郎

Slide 2

Slide 2 text

概要 反省会ということで、 ・React プロジェクトのプルリクエストなどを読み返して みた。 ・何回か繰り返し議論されている論点があった。 ・いくつか書き起こしてみた。 という話です。

Slide 3

Slide 3 text

以下、Q & A が続く流れで進みます

Slide 4

Slide 4 text

Q. this.state へ直接代入しても良いですか?

Slide 5

Slide 5 text

こういうコードの是非の議論

Slide 6

Slide 6 text

A. ダメです!

Slide 7

Slide 7 text

React の仕様上は、このように直接代入せずに、 setState() の引数で更新することになっています。 理由: そもそも仕様では無い マニュアル) https://facebook.github.io/react/docs/react-component.html#setstate

Slide 8

Slide 8 text

> Never mutate this.state directly, as calling setState() afterwards may replace the mutation you made. 引用元) https://facebook.github.io/react/docs/react-component.html#state > The only place where you can assign this.state is the constructor. 引用元) https://facebook.github.io/react/docs/state-and-lifecycle.html#do-not-modify-state-directly また「代入を禁止する」という点が、特に各所で強調されています。

Slide 9

Slide 9 text

ドキュメントに明確な記述がなかったので推測になりますが・・・ setState() は同期的に描画を行う関数ではないため、 this.state への代入を許してしまうと、setState 呼び出し時の state の値を確定でき なくなってしまうからだと思っています。 禁止されている理由を考える

Slide 10

Slide 10 text

過去の事例を見るに、state へ直接代入するコードを書いた理由は、Component 内 部に再描画を伴わないで更新できる変数が欲しいからでした。 その場合、this.state 内に格納するよりは、 任意のインスタンス変数を定義した方が良いです。 react-redux の Provider https://github.com/reactjs/react-redux/blob/master/src/components/Provider.js react-transiton-group の TransitionGroup https://github.com/reactjs/react-transition-group/blob/master/src/TransitionGroup.js いくつか react オーガニゼーション下のライブラリを確認したところ インスタンス変数を使ってたので、良さそうと思いました。 代替案

Slide 11

Slide 11 text

Q. React Lifecycle 内で        Actionを発行してもいいですか?

Slide 12

Slide 12 text

こういうコードの是非の議論

Slide 13

Slide 13 text

A. ダメです!

Slide 14

Slide 14 text

まずひとつ、先ほどの例の場合に、わかり易い問題点としては、 状況によって無限ループしてしまうことが挙げられます。 Flux や Redux における「Action の発行」は、 最終的に、描画処理の実行までも含むことを意味しているため、 場合によっては再度 componentDidUpdate が発火し、 無限ループの状態になってしまいます。 理由: 無限ループ

Slide 15

Slide 15 text

Q. じゃあ、無限ループしなければ良いの?

Slide 16

Slide 16 text

shouldComponentUpdate で防げば良いじゃん! componentWillMount なら大丈夫だよね?

Slide 17

Slide 17 text

A. それもダメだと思う・・・

Slide 18

Slide 18 text

React コンポーネント側としては、描画に関する全ての情報が含まれた props さえもらえれば一度の描画フローで完結できるはずです。 それに対して再び描画フローを発生させたいのは、React 以外の都合で す。 だからダメなんじゃないかなぁという結論に、現在はなっています。 理由: Reactの都合上は不要 (また、知ってる限りだと enzyme を使ってユニットテストを書くときに困る。 サーバサイドレンダリングでも同じ?)

Slide 19

Slide 19 text

Q. Reactを使うと何が良いんですか?

Slide 20

Slide 20 text

“React” の名前は知れ渡って居るので サーバサイドやデザイナーの方から良く聞かれます

Slide 21

Slide 21 text

ドキュメントを参考にしたけど難しい 宣言的: 状態からビューを設計して、データに変更があれば即座に描画する。 宣言的なビューはコードの予測性を向上し、デバッグを容易にする。 コンポーネントベース: 自身の状態のみを管理する部品を作り、それらを組み合わせて複雑なUIを 作る。 多くのデータをアプリに渡すことが容易にでき、DOM外に状態を保持するこ とができる。 引用・訳は一部略) https://facebook.github.io/react/

Slide 22

Slide 22 text

「宣言的」「コンポーネントベース(=指向?)」 という概念が消化できてない

Slide 23

Slide 23 text

A. とりあえず知ってる範囲で答えてます { “input”: { “visible”: false, “value”: “” }, “list”: [] } { “input”: { “visible”: true, “value”: “foo” }, “list”: [ { “message”: “One” }, { “message”: “Two” } ] } すごいUI UIの状態を表現するデータ Reactコンポーネント群 すごいUI foo ・One ・Two Reactを使うことで、外から渡さ れたデータの値に対して、 UIが 一意に表現されることを保証で きる。 それを保証すると、UIの誤りは データの誤りになるため、デ バッグが楽。テストも書きやす い。

Slide 24

Slide 24 text

あー、いいっすね! そう・・・。 なお、その結果は両極です(後者が多い印象)

Slide 25

Slide 25 text

Thank you!

Slide 26

Slide 26 text

最後にいつもの マネーフォワードは、 エンジニアを募集しています! (フロント・Ruby/Rails・Java・iOS・Android 等)