一人もくもく会 α verでサービス開始しました。
請求書作成システム α verでサービス開始しました。

Twitterを作る 第4回 コンポーネント構成考察

Reactのコンポーネントの構成にちょっと悩んだのでメモ。

現在ログイン後の画面はreact-routerでルーティングしている。(まだ1画面しかないが) コンポーネントの構成は下記のようになっている。

  • Main (routing)
    • MainIndex (メインページ)
      • MainHeader (共通ヘッダ)
      • MainPosts (投稿一覧)
        • MainPost (投稿表示)

一体何を悩んだかというと、MainHeaderは各ページで共通で利用するため、本当は元々下記のようにしていた。

  • Main (routing)
    • MainHeader
    • MainIndex (メインページ。ここをroutingで切り替える)
      • MainHeader (共通ヘッダ)
      • MainPosts (投稿一覧)
        • MainPost (投稿表示)

問題1

ただ、これだと問題があった。 投稿はMainHeader内にネストするフォームで行うが、その際に最新の投稿一覧をMainPosts側に読み込ませたい。 しかしMainHeaderとMainPostsは親子関係で連なっていないため、連携ができない。

問題2

posts(投稿配列)のstateをどこに持たせるかという問題。 なるべくMainで持たせたかった。何故かと言うと、MainHeaderには検索ボックスなどもあるので、 それのハンドリングのコードも記述しなければならないが、 MainHeaderを下の方においてrender時にDOM指定するとそのコードを何度も書かなければならない。

構成の解決

DOMにrefを付けることによって子コンポーネントのメソッドを呼べたりするのでその辺りも考えたが、

Refsの詳細 | React 0.13 日本語リファレンス | js STUDIO

の下の注意を読んで欲しい。

Reactを使用したプログラムの開発経験が乏しいと、 アプリケーションで"何かを実現する"のに、すぐにrefsを使いたくなるかもしれません。

このような場合は、stateがコンポーネント階層の何処で所有されるべきなのかを、もう少し注意深く考えてみて下さい。 その結果、より高い階層でstateが"所有"されるべきであると判明することがよくあります。

つまり色々なところで使いまわしたい値はなるべく高い階層に置けということだ。 なのでMainIndex、つまりルーティングで切り替えられる各ページのトップに置くことに決めた。

コード重複の解決

上記方法で対応すると、各ページごとに同じコードを書かなければならなくなる。 なのでそれは各ページのRootはMainBaseRouteComponentという継承用クラスを作り、 全てのrouterから呼び出されるページ(MainIndex等)はこれを継承することにした。 これで全部のページでMainHeaderを配置してもいちいちhandlerメソッドを書かなくてよくなった。

Dumitter https://alphabrend.sakura.ne.jp/dumitter/

Twitterを作る 第5回 フォロー - アルファブレンド プログラミングチップス