タオルケット体操

サツバツいんたーねっとでゲームとかガジェットのレビューとかをします

ReactにおけるBreadcrumb(パンくず)実装のパターン

もちろんケースバイケースなんだけど、パンくずリストというのは全体のレイアウトに属していながらマウントされる要素に従属して中身が変わるという点でちょっと厄介。
具体的にどういうケースで厄介かというと、ヘッダやサイドバーなどをまとめたpage layout的なコンポーネントを大枠に作り、内部の表示をreact-routerで切り替えている場合。業務アプリとかでやりがちなんじゃないかなとおもう。

ざっくりお気持ち擬似コード。

const PageLayout = (breadcrumbs: readonly Breadcrumb[]) => {
  <Layout>
    <Header breadcrumbs={breadcrumbs} />
    <Sider />
      <Main>
        {children}
     </Main>
    <Footer />
  </Layout>
};

const Routes = () => {
  <PageLayout breadcrumbs={/* どうやってひねり出すか */} />
    <Switch>
      <Router ... />
      ...
    </Switch>
  </PageLayout>
};

はい。

まぁ色々とやり方はある。例えばRoutingされるcomponentで、都度PageLayoutを宣言するとか。ReduxのStoreと連動させるとか(ダルい)。
でもダルいよね(ダルいよね)? react-router自体の賛否はともかく、react-routerが意図してる省力化の機能活かせてないし?

さらにさらに、パンくずリストってのは「Routingそのものと密結合」な要素なので、Routingされるcomponent内部でパンくずリストの表示を制御してしまうと「子供のコンポーネントは親に関心を持たない」という鬼原則が崩れてしまう。当たり前だけどPresentationalComponentは描画以外の状態や振る舞いに依存してはいけない。
愚直にやろうとすれば他にも色々あるだろうけど、ルーティングの二重管理とかあまりやりたくない。URL変えるのめんどくさくなるし。

Reactの「親から子へ」の鉄則を守りつつ、DOM上は別の場所で描画してぇ……
はいそうです、Portalがありますね。でもPortalを直接使うとコード上にDOMが露出しちゃって抽象度に欠けますね。ということで思いつきで書いたコードがこれです。

これを使うとこんな風に書けます。

const { Zone, ExitGate, EnterGate } = createSplitGate((arg: BreadcrumbItem[]) => <AwesomeBreadcrumbComponent items={arg} />);

const PageLayout = (breadcrumbs: readonly Breadcrumb[]) => {
  <Zone portalID="awesome-id-for-breadcrumb-location">
    <Layout>
      <Header />
      <ExitGate />
      <Sider />
        <Main>
          {children}
       </Main>
      <Footer />
    </Layout>
  </Zone>
};

const Routes = () => {
  <PageLayout />
    <Switch>
      <Router ... render={routeProps => 
        <>
          <EnterGate arg={[un, duex, trois]}
          <Presenter ... />
        </>
      } />
      ...
    </Switch>
  </PageLayout>
};

はい。
ExitGate とか EnterGate だと汎用的すぎて何が何だかなんで、実運用するときはもっと明示的な名前でaliasを作ってあげましょう。今気がついたけど Enter じゃなくて Entrance のほうが適切か? まぁいいか。

「DOM構造と機能とスタイリングを分離する」ってのはデザインに凝れば凝るほど難しくなるんですが、そういうときにportaは便利なので使っていきましょうねという話でした。
ちなみにほんとは関数名はPortalにしたかったんですが、React本体の名前とだだ被りするのでSplitgateにしました。ゲーマーなら元ネタがわかるとおもうのでSplitgate: Arena Warfare行為しましょう。

以上。

You are gonna obviously need itの法則

YAGNIの原則

YAGNIの法則はご存知ですか。
You Ain’t Gonna Need It. の略で、アジャイルとかでよく言われる「いらんもん作るな」の原則ですね。

「これいるやろー」で前もって作りこまれた機能は10%しか使われないし時間の無駄だよね(10%の根拠はあるんかな)、っていうあれです。

「まだ必要じゃない」って意訳する人もいますがこれは悪い意訳です。

続きを読む

フロントエンドエンジニアをやっていくために本当に必要な技能

「俺はフロント開発者じゃない、ただフロントが得意で書く機会が多いだけなんだ」といいながら日々ジャバScriptの中でもがいています。

採用の面談に顔を出したりする機会ができてきたのでここら辺で一度言語化しておきたい。

勘なんですが、たぶん心の強さです。

続きを読む

React HooksとTypeScriptを使ったRedux再実装で理解度を深める試み しましょう

React Hooksでましたね。
これでクラスを使う必要がなくなってみんなハッピーです(公式で再三書かれてますが、既存のコードをHooksで書き直す必要性はないです)。

それはそうとして、useReducer という新しい仲間が増えました。
ちょっと前に追加されたContextと合わせることでReduxを置き換えることができます(置き換える必要があるかどうかは考えてはいけない)。

しかし最近気がついたのですが、そもそもReduxがどういうものなのか、雰囲気で使っている人が多いようにおもいます。
ぶっちゃけ「ドキュメントやソースコードを読めばいいやんけ」、で終了する話なのです。
とはいえReduxは特定のViewライブラリへの依存を防ぐように作られていたり、なるべく縛りを作らずに薄い実装にしてプラグインで解決していくような思想になっていたり、フレームワークというよりはフレームワークのためのフレームワーク、つまりメタフレームワーク的な感じだったり、とにかくまぁそういったあれこれでわかりにくく、なんとなく既存の実装をコピペって動くコードを作っちゃってるのかなぁとかそういう風に想像しています。

それはほんとうによくないのでこれを機にちゃんと理解しましょうね、ということですでに何番煎じかになっているかもしれませんがReact Hooksを使ってReduxを再実装してみます。

続きを読む

エンジニアリングの「橋」について

橋とはなんですか。
ドラゴンクエストというゲームを知っていますか。かのゲームにはこういうセリフがあります。
「はしに きをつけろ! はしをわたって とおくにいくほど おそろしい まものたちが あらわれるだろう」

昔のRPGほどこういった傾向が顕著なんですが、ドラゴンクエストにおいて敵の強さというのはなだらかな曲線を描くものではなく、大陸を横断するごとに階段状にあがっていきます。レベル10で無双していても、一つ橋を渡った瞬間敵がギラなどを使い始めホイミを使う暇もなく主人公は死にます。

続きを読む