react-redux-code-reading#meguroes

 react-redux-code-reading#meguroes

react-redux の中身を読んでみた発表

react-reduxと、おまけでパフォチューの仕組みについて話しました。

33ef4c1ebe619115b552db9a9f9a3509?s=128

sadnessOjisan

April 04, 2019
Tweet

Transcript

  1. react-redux code reading! Yuta Ide ( @sadnessOjisan ) Meguro.es #20

  2. Yuta Ide @sadnessOjisan (Twitter / GitHub / Qiita ) JavaScript⾒習い

  3. 肩エラーがひどい Yuta Ide @sadnessOjisan (Twitter / GitHub / Qiita )

    JavaScript⾒習い
  4. 休⽇は、web廃墟コンポーネントライブラリを作ってます https://github.com/sadnessOjisan/re-geo

  5. 今⽇のTOPIC react-redux source code reading

  6. 準備中の出来事 Danが全く同じことをしていたことに気づく! (しかも3年前に!!) https://www.youtube.com/watch?v=VJ38wSFbM3A 17. React Redux with Dan Abramov

    / readthesource
  7. react ‒ reduxをざっと復習 • redux / react-redux はReactの状態管理に使う • props

    バケツリレーの解消 • コンポーネントのポータビリティがUP • store に対して, componentから read, dispatch することができる • 上の仕組みをprovider と connect で 実現
  8. おなじみのconnect • createConnect という⾼階関数の返り値 • この返り値(関数)は、 Ø mapStateToProps Ø mapDispatchToProps

    Ø mergeProps Ø options を引数にとる
  9. ところで mapStateToProps, mapDispatchToProps って関数じゃなくてもいいんです。

  10. match • createConnectの中で実⾏される • どういう形をとりうるかは 内部で配列の形 で保持している • 配列を⾛査し、今後ライブラリ内で使うた めのmapStateToProps,

    mapDispatchToPropsを作る 関数が渡された時の処理 objが渡された時の処理 match内で回される
  11. connect()が返すもの • connectHOC(selectorFactory, options){} • connectHOC, selectFactoryにはデフォルトの値が⼊れられている => connect()は, connectAdvanced(defaultSelectFactory,

    option) を返す => connectAdvancedという元からある関数にデフォルトの設定を⼊れておい てくれたものがconnectとしてexportされている デフォルトの値
  12. connectAdvanced()が返すもの • connectAdvancedは、wrapWithConnect(WrappedComponent){} を返す。 これは「あるpropsを付け⾜したComponent」を返す関数

  13. さっきから関数を返す関数ばっかりやんけ!!!! (あとで全体像を図でお⾒せします)

  14. では、wrapWithConnectは何を返しているでしょう? ↓ <ContextToUse.Consumer> </ContextToUse.Consumer>

  15. ContextAPIの復習: reduxのstoreが各コンポーネントが参照できる理由 • React v16.3 からContextAPIが公開 • Propsバケツリレーしなくても、データを流せ、共有できる仕組み (Context provides

    a way to pass data through the component tree without having to pass props down manually at every level.) • つまり、reduxで作られたstoreがContextの仕組みを使って、コンポーネント 間で共有されている • Providerで与えられた値を、consumerが⾃由に取り出す https://reactjs.org/docs/context.html
  16. ContextAPIの復習: reduxのstoreが各コンポーネントが参照できる理由 • React v16.3 からContextAPIが公開 • Propsバケツリレーしなくても、データを流せ、共有できる仕組み (Context provides

    a way to pass data through the component tree without having to pass props down manually at every level.) • つまり、reduxで作られたstoreがContextの仕組みを使って、コンポーネント間 で共有されている • Providerで与えられた値を、consumerが⾃由に取り出す https://reactjs.org/docs/context.html
  17. react-redux使うときに、ルートでProviderで囲いましたよね? ここで流したstoreをConsumerは⾒ている!!!

  18. 実際のところ、react-reduxのProviderは何をしているのか propsからstoreを取り出して stateにセットし、 そのstateをConsumerに 流している!

  19. 話を wrapWithConnect に戻すと • providerから受け取ったstoreを使って、新しいpropsを作る • そのpropsを詰めたcomponentを返す wrapWithComponentをたどった先

  20. 話を wrapWithConnect に戻すと • wrapWithComponentはproviderから受け取ったstoreを使って、返すコンポーネ ントのpropsを作り出し、それをcomponentのpropsに詰め込んで、その componentを返している = connect()(Component)の実⾏結果を返している •

    その加⼯処理は、selectDerivedPropsが⾏なっている selectDerivedProps が connenct()()の 返り値(コンポーネント)のpropsを決めている connectがwrapしたcomponent に、渡したいprops propsをコンポーネントに⼊れ る処理
  21. 話を wrapWithConnect に戻すと • wrapWithComponentはproviderから受け取ったstoreを使って、返すコンポーネ ントのpropsを作り出し、それをcomponentのpropsに詰め込んで、その componentを返している = connect()(Component)の実⾏結果を返している •

    その加⼯処理は、selectDerivedPropsが⾏なっている selectDerivedProps が connenct()()の 返り値(コンポーネント)のpropsを決めている Connectがくるんだ componentに渡したいprops propsをコンポーネントに⼊れ る処理 selectDerivedPropsは何をしている?
  22. selectDerivedPropsは何をしている • storeが更新されたかを確認し、更新されて⼊ ればconnect()()で返すコンポーネントのprops を更新する • どのように更新するかは、selectorFactoryが決 める propsの更新の仕組みはselectorFactoryが握っていた

  23. selectorFactoryってなんだっけ • createConnect()の説明で出てきた • デフォルトで、 finalPropsSelectorFactory が代⼊されている (/src/connect/selectorFactory.js) • selectorFactoryの実態は、pureFinalPropsSelectorFactoryを実⾏した結果

  24. pureFinalPropsSelectorFactoryを覘くと stateやpropsの更新を監視して、処理を仕分けている

  25. pureFinalPropsSelectorFactoryを覘くと stateやpropsの更新を監視して、処理を仕分けている ⽐較⽅法はoptionで指定する

  26. handleXXXそれぞれの処理を覘くと 必要なpropsをmergePropsでかきあつめている

  27. mergePropsってなんでした? connect()()が返すコンポーネントに詰め込まれる、 最終的なpropsを作っている connect()の第三引数

  28. pureFinalPropsSelectorFactoryは結局? 「state と props を受け取ると、計算済みの mergedPropsを返す関数」を返す関数 connect()で呼び、 「state と props

    を受け取る と、mergedPropsを返す関数」を作り、実⾏する 実⾏して得られたmergedPropsがconnect()()の返すコンポーネントに詰め込まれている。
  29. react-reduxがやっていること: 次のPropsを計算して、詰め込んで返す

  30. ざっくり図 connect connectAdvanced Component selectDerivedProps makeChildElementSelector SelectorFactory match mapStateToProps mapDispatchToProps

    sourceSelector Props 内部で使うmst, mdpを決める Dispatchする役割 Stateを読む役割 Componentに⼊れるpropsを決める propsを⼊れ替えるか判定する propsとして詰め込む デフォルト設定を読み込む componentを設定する関数を返す export default propsを決める関数を返す
  31. Q. 中を読んでみて、嬉しかったことは?

  32. A. パフォチューの⽅法がなんとなく理解できた

  33. • なんでconnect()にちゃんと引数を渡すのか? • なぜreselectでメモ化するのか? • 第四引数に何を渡せばいいのか? 例

  34. 不要な再レンダリングを抑制 selectorFactory.js connectAdvanced.js connect()()は、propsに変化がな ければ、新しいコンポーネントは 返さない

  35. 不要な再レンダリングを抑制 selectorFactory.js connectAdvanced.js connect()()は、propsに変化がな ければ、新しいコンポーネントは 返さない storeの変更を元にcomponentに 詰め込むpropsを決めているのは SelectorFactory

  36. 不要な再レンダリングを抑制 selectorFactory.js connectAdvanced.js connect()()は、propsに変化がな ければ、新しいコンポーネントは 返さない storeの変更を元にcomponentに 詰め込むpropsを決めているのは SelectorFactory 詰め込むpropsを変える必要があ

    るかの判定ロジックをoptionで指 定できる
  37. 不要な再レンダリングを抑制 selectorFactory.js connectAdvanced.js connect()()は、propsに変化がな ければ、新しいコンポーネントは 返さない storeの変更を元にcomponentに 詰め込むpropsを決めているのは SelectorFactory 詰め込むpropsを変える必要があ

    るかの判定ロジックをoptionで指 定できる 最適化の余地がある
  38. areStateEqualの使い⽅ • areStateEqualはconnectの第四引数のoption(関数) • Trueを返すと、mapStateToPropsが実⾏されなくなる • areStatesEqualはデフォルトでは、新旧のstateを shallow に strict

    ⽐較 https://react-redux.js.org/api/connect#options-object 感⼼があるstate以外が変わった場合でも、再レンダリングが⾛る (関⼼外のstateを⽐較すると、falseを返し得るので)
  39. 対策:⽐較したい部分だけで⽐較するように設定する https://react-redux.js.org/api/connect#options-object Todosが変わった時だけ、mapStateToPropsが実⾏される!

  40. コードを読んでみて • パフォチューがどういう原理で可能になっているのかを知れて、楽しかったで す! • react ‒redux 完全に理解した!!!! と思いきや…

  41. v7のアプデで⼤幅に変わります!!!!! https://github.com/reduxjs/react-redux/issues/1177 https://github.com/reduxjs/react-redux/releases/tag/v7.0.0-beta.0

  42. 次のアプデで⼤幅に変わります!!!!! https://github.com/reduxjs/react-redux/issues/1177 https://github.com/reduxjs/react-redux/releases/tag/v7.0.0-beta.0