console.lealog();

@leader22のWeb系に関する勉強めもブログですのだ

Reactでちょっとしたサービスを作りました

みなさんマリオカート8やってますか?
200ccは速すぎて難しすぎるので、結局オンラインなGWですどうも。

春になりDLCも増え、そろそろカスタマイズを一新したいとか考えてま・・すよね?
そんなあなたのために、WiiUを起動しなくてもカスタマイズを考えられるサービスを作りました!

特にReactである優位性はないんですけど、流行ってるので触っておきたかったんです!

はじめに

ReactとReactRouter x Require.jsだけのシンプル構成です。
ES6でJSXです。

ソースコードも置いておきます!

GitHub - leader22/mk8-kart-customizer: Mario kart eighhhhhhhhhhhhhhhht!

ごめんなさい案件

  • サーバーサイドレンダリングまわりは興味がないのでやってません。
  • パフォーマンス最適化も実機検証もほぼやってません。
  • Fluxなる考え方も高尚すぎたので一旦スルーしてます。

根本的に間違ってるーとか、こうしたほうがいいのではーとか、あればこっそり教えてください!
もしくはForkしていい感じにしてください!

ざっくり所感

ES6

DestructuringとかTemplateStringとかもう楽過ぎて日々の業務に支障をきたしそうです。
あとBabelがJSXを解釈してくれるのに感動しました。

class作る汎用関数みたいなのがコンパイルするとclassの数だけ吐かれるとかは気になるけど、
そんな容量を気にするよりも、日々の精神衛生のために導入しちゃっても良い気はしました。

さすがにiOS5.xとかAndroid4.xで動かないAPIとかないよね・・?
ES5がだいたい動けばいけるよね・・?

React

最初は「一体何者なんだー」感があったんですが、今となっては全然薄っぺらいViewまわりのライブラリやなーと思えてます。

JSXも最初は抵抗あったんですけど、コードの見通しが全然違うので使う場合は必須な気がしてます。
というか、JSXの記法を制するものがReactを制する気がしてます。

React Router

まぁ仕方ないというかなんというか、初見の取っ付きにくさがすごかったです。
ルーターのくせになんでJSXやねんってきっと思うはず。

でもまぁ使ってみるとなるほどねーとなり、だんだん好きになっていくと思いますw

思うところ

コンポーネント化の功罪

js内にHTMLを書くってのはやっぱりどうにもこうに抵抗があります。
というのも、文言修正するだけでビルドしなおしてキャッシュを破棄させるってどうなんだってのがあり。

バックエンド向けとかPCとかなら気にしなくて良いと思うんですけど・・。

こうなるともはや差分更新は大変というか無理で、
一周回ってAMDにせめてワンチャンな気がしてhttp2はよっていう気持ちになりますが結局リクエスト数減らすにこしたことはないのでやっぱり辛い気がしています。

CSSどうするんだ問題

jsの世界にHTMLを持ってくるとこまでは達成され、次はCSSだってフェーズなんでしょうか。
でもこれボタンの色変えただけでビルドしなおし(ry

ちなみに今回、Radiumってのを使ってみようかと思ったのですが、読み込むだけで何故か全部動かなくなったのでやめました。

あとそもそもコレ系のものはbefore/after疑似要素に対応しないぽく、そもそも使えないコなのではというのが正直な気持ち。
ベンダープレフィックスの対応もまだ追いついてないっぽいし、色々まだまだですねー。

コンポーネントってなんなんだ問題

Marionetteの時もそうでした。
いわゆるRootなコンポーネントだったり、他の部品を内包するMarionette.Region的なコンポーネントをどう分類すべきか。
ちなみに今回は、Routerから叩かれるものをControllerView、その他をただのViewって扱いにしました。

あとは仕事なくてもList -> ListItem とするべきか、もうListだけでええやんってするか問題も相変わらず。
コンポーネントっていう言葉の響き的には、ひたすらに正規化して細分化すべきなんでしょうけどねー。

renderごちゃごちゃする問題

上記の件もあり、こみ入ってくるといわゆるView変数を用意するコードが増えてきてどんどん行数が・・!
でも別ファイルに切り出してもどうせ必要なのはstate/propsであってその定義は本体側のファイルにあるわけで、となるといっそ一つに固まってる方がわかりやすいがしかしうーんっていう。

コンポーネント専属のprops/stateをもらってView変数だけ返すマンを作るとかしたら良いのかな?

そのstateは誰のものなんだ問題

どっか1つで全てのstateを管理して、Rootからぜーんぶpropsで渡す。
例外は認めない!みたいな構成にすればよかったのではと今さら思ったりしている。
そしてそうなると中継イベントprops祭りになるのは目に見えてるから、一旦グローバルに返すようにしてまたRootからデータ流して・・ってのがFlux?

でももしそうならReactとしてもComponentとRootComponentみたいな役割を分けた実装になってても良い気がするし、
やはり適当なレイヤーで適当なstateを持つべしっていう示唆があるのではと深読みしてみたりして結局よーわからんです。
誰か筋の良い設計指針を教えてください。

ハマったところ

JSXでコメント

render() {
  return (
    {/* こうしないとコメントにならない */}
  );
}

Numberなprops

<Counter initCount={5} />

"" でクオートされた文字列か、{} で表現したものしか渡せないので、数値だけでも{}で囲む必要あり。
違和感は慣れ。

onClickしたいaタグにはhrefを

<a href="" onClick={this._onClickHandler}>属性ないと動かない</a>

html5的には良かったはずですが・・。

空でも良いのでhrefがないと、iOSで動かなかったです。
prevDefするのお忘れなく。

インラインリン

<p>こういう文字の中に、こんな<a href="/top">リンク</a>があったら</p>

どうコンパイルされるかというと、

<p>
  <span>こういう文字の中に、こんな</span>
  <a href="/top">リンク</a>
  <span>があったら</span>
</p>

こうなるんですが、このおかげでリンクの前後に謎のスペースが・・・。
PCのSafariでだけ起きてたので無視した。

Reactなのかreactなのか

ライブラリによっては"React"って呼んでたり"react"って呼んでたり。
Requireのパス解決でなんとかなるけども、統一してほしいなーという愚痴。

JSXで無理やりif文

render() {
  return (
    { isFoo ?
    <span>Foo</span>
    : '' }
  );
}

renderの外で変数にJSX詰めるの嫌いなだけです。
サボり癖ですね。

おわりに

作ってみたは良いものの、いわゆるベストプラクティスやら真意やらを押さえた構造にはなってないなーと一晩寝かして思う今日このごろです。
ま、流れてくる記事だけ読んでできたつもりになるよりかはマシだと思うので、良しとしましょう。

諸先輩方のもうちょっと規模の大きいものを作る場合のファイル構成とかデザパタとか、
そういう知見のシェアを待ってます。(マリオカートしながら