Reactについての良くある問答

Ca5155379b85b4bf910e431207f832ec?s=47 kjirou
May 10, 2017

 Reactについての良くある問答

Ca5155379b85b4bf910e431207f832ec?s=128

kjirou

May 10, 2017
Tweet

Transcript

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

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

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

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

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

  6. A. ダメです!

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

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

  10. 過去の事例を見るに、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 オーガニゼーション下のライブラリを確認したところ インスタンス変数を使ってたので、良さそうと思いました。 代替案
  11. Q. React Lifecycle 内で        Actionを発行してもいいですか?

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

  13. A. ダメです!

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

    が発火し、 無限ループの状態になってしまいます。 理由: 無限ループ
  15. Q. じゃあ、無限ループしなければ良いの?

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

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

  18. React コンポーネント側としては、描画に関する全ての情報が含まれた props さえもらえれば一度の描画フローで完結できるはずです。 それに対して再び描画フローを発生させたいのは、React 以外の都合で す。 だからダメなんじゃないかなぁという結論に、現在はなっています。 理由: Reactの都合上は不要

    (また、知ってる限りだと enzyme を使ってユニットテストを書くときに困る。 サーバサイドレンダリングでも同じ?)
  19. Q. Reactを使うと何が良いんですか?

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

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

    https://facebook.github.io/react/
  22. 「宣言的」「コンポーネントベース(=指向?)」 という概念が消化できてない

  23. 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の誤りは データの誤りになるため、デ バッグが楽。テストも書きやす い。
  24. あー、いいっすね! そう・・・。 なお、その結果は両極です(後者が多い印象)

  25. Thank you!

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