🍃このブログは移転しました。
3秒後、自動的に移動します・・・。

#ウデマエアーカイブ をReactで書き直した件に関するメモ

スプラトゥーンのウデマエを可視化するサービスを - console.lealog();

イカのゲームが発売されたのが去年の5月。
↑の記事を書いたのが去年の8月。
よもや1年に渡って同じゲームをやり続けることになろうとは・・・。

というわけで

録画系ガチ勢はIkalog x stat.ink、iOSApp勢はイカキロク、Android勢はイカレコ、その他もろもろ。

とまぁ色んなサービスが世の中には出てきましたが、そんな中でも未だにぼちぼち利用者がいて驚いてるのがこのWeb版のウデマエ管理サービスのウデマエアーカイブです。

作った当初はVue.jsを使ってて、割と勢いで作りました。
なのでその後の機能追加はどんどん難航し、あれよあれよと更新しなくなったのが去年の暮れです。

そんな中、先月にVue.jsの2.0が発表されて、これはアップデートのチャンス!ついでにリファクタのチャンス!と思ったけど・・。

というわけでReactへ

リニューアルやりかけてやめるのはアレだったので、手に馴染み始めたReactでやることにしました。

今回のてくのろじーすたっく from `package.json`

  • "chart.js": "^2.1.2",
  • "object-assign": "^4.1.0",
  • "react": "^15.0.2",
  • "react-dom": "^15.0.2",
  • "react-router": "^2.4.0",
  • "react-tap-event-plugin": "^1.0.0"

まぁわかりやすいですね。

`tap-event-plugin`は結局`v15`になっても必要っぽいので、仕方なし。

Flux系のライブラリは使ってません。
というのも、既存のコードのMVC意識なMの部分を使いまわせそうだったので、State管理する系コンポーネントでそれ叩けばいいかなーと。

となるとStore用意するのも面倒やし処理をActionに切り出すのも面倒やしそもそも更新処理そんな無いしってことで、愚直なReactスタイルで。

ソースコードはこちらです。

github.com

Fluxとはなんだったのか

個人的にはooってライブラリを入れたからFluxとかそういうのでは無いと思ってて、

  • とあるデータ構造があって、それをまんまDOMにしてくれるのがReact
  • そのデータ構造を更新する箇所は限定する(≒ rootComponent)
  • するとデータの流れが自然と単方向になる

みたいなReactさわってると誰もがたどり着くであろうパターンになれば、もうそれはFluxってくくりでいい気がしてます。
別にStoreがなくたってActionでやりとりしなくたって。

ディレクトリ構造

- component/
- model/
- page/
- reducer/
- const.js
- main.js
- router.jsx
- util.js

こうなった。

  • `component`がいわゆる状態をほぼ持たないコンポーネント
  • `model`はv1から続投のMVCのMで、`localStorage`をゴニョるおじさん
  • `page`ってのがルートごとに`state`を管理するコンポーネント
  • `reducer`はModelを`state`にする手前に噛ませるPureな関数で、`page`の単位で存在させる

このへんのネーミングのベストプラクティスがあれば知りたい今日このごろ。

ライブラリ個別の知見たち

React Router

知らん間にパワーアップしてて、驚きでした。

`component`じゃなくて`components`ってのを使えば、親に`props`で渡せるのに感動した。
Angularのui-routerとかも似たような機能あったなーと思いながら。

module.exports = (
  <Router history={hashHistory}>
    <Route path="/" component={Master}>
      <IndexRedirect to="record" />
      <Route path="record" component={RecordPage}>
        <IndexRedirect to="graph" />
        <Route path="graph" component={GraphPage} />
        <Route path="list"  component={ListPage} />
      </Route>
      <Route path="stat"   component={StatPage} />
      <Route path="input"  component={InputPage} />
      <Route path="others" component={OthersPage} />
    </Route>
  </Router>
);

こんな感じのルート構造。

Chart.js

これが一番の驚き。
知らん間にv2になってて、ドキュメントも綺麗になってた。

設定の細かさだとやはり、HighChartsやらd3やらに軍配は上がるけども、ライトな触り心地って意味では取っ付き易くて非常に良いと思います。

Y軸を左右ともに表示したい

ココに一番ハマったのでメモ。

これをやりたい場合、`datasets`に同じデータが2つ必要です。
かつ、axisのmin/maxも同じにする必要があります。

そして、`bar`チャートで2つデータを渡すと、表示されるバーの幅を2つが折半してしまうので、片方は`line`チャートにして透明で描画するとかしないといい感じに表示できないです。
`barPercentage`とか、`categoryPercentage`とかを絶妙に調整すれば2本を1本に見せかけることもできますが、オススメはしない方向という結論です。

とにかくこれにめっちゃハマったけど、それ以外はすごく良くなってた。

React道で悩んでるところ

Util的な関数を、どこまで`render`で使うのか

`props`で渡された時点で既に期待する形になってるべきってのもわかるけど、元ネタは同じやけど見せ方が異なる場合に2つ用意すんの?とか考えたら面倒になった。

  • あくまでプリミティブなデータとしてざっくり処理してから`props`に渡す
  • `950 => S50` みたいな見せ方に関する処理は、Utilを個別に

ってしてるけどうーむ。

Const的なものを、どこまで渡すか

これもほぼ同上。
Contextで渡しちゃうとかでもいいけど、どうせ変わらないものなのであればコンポーネントから直接触っても一緒ではないかっていう。

モジュールとしては依存するわけやけど、それによって何か挙動が変わるわけでもないし・・・。

というわけで

あらためてv2になったウデマエアーカイブイカよろしくーー。

leader22.github.io