React+TypeScriptに入門した

合計で20時間くらいいじったところでチュートリアルから離れて作りたいモノを作れる手応えが出てきた。
「完璧に理解した」から「分からないことが色々とある」に進化。

最初は取っつきにくいかんじあるけど分かってしまえば割とシンプル。
この取っつきにくい感はどこから醸成されるんだろう。

ある程度分かった後も一から書こうとするとやっぱちょっとしんどいので、そういうところかな。
コンポーネントがある程度組み上がると楽だけど、そこまで組み上げるのが大変みたいな?

またSPAを構築するためのルーティングや、コンポーネント間で状態を共有するRedux(Flux)などを含めると学習コストが更に高まる。
Redux使った場合、コードの書き方に強い指針がないので悩む面もあり。

参考にした本

りあクト!

  • https://oukayuka.booth.pm/items/1044097
  • 対話形式で読みやすい
    • でも抵抗なく読めすぎて読み終わった後に意外と頭に残ってないパターン
    • 都度読み返し
  • Reactの開発環境についてなど色々と参考になる
  • いざ自分のコードを書こうとすると他のリソースがないと厳しい => 公式ドキュメントなど
  • 最近のJavaScriptやTypeScriptについてもキャッチアップできる
  • 取っかかりとしてはかなりいい

速習 React 速習シリーズ

  • Amazon
  • Kindle Unlimitedに入っていたので
  • 短いのでサクッと読める
  • 概要を掴む/再確認するのには良い
  • 安いけど買って読むくらいなら公式ドキュメントで良いかんじあるかな?

Reactの開発手順

  • JSXで記述したコンポーネントを組み合わせてアプリケーションを構築していく
    • モジュール化したHTMLとJavaScriptの塊をHTMLタグのように使う
  • 画面を構成するパーツをコンポーネントとして作っていく
    • 大きくざっと作って小さなコンポーネントに切り出してもいいし、小さく作ったコンポーネントを大きく組み上げていってもいい
    • プログラミングでクラスやメソッドを切り出したり組み立てたりするやり方と変わらない
    • 関数コンポーネントにrecomposeでstateやhanderをペタペタくっつけるのがスマートらしい
  • コンポーネントに結びつくデータ(State)が変更されるとコンポーネントは再描画される
    • propsでデータを受け渡し、propsの値をもとにstateを変更すれば再描画
    • イベントのコールバックでstateを変更すれば再描画

Thinking in React

https://reactjs.org/docs/thinking-in-react.html

  1. デザインモックからスタートしてUIをコンポーネント階層に落とし込む
  2. Reactで静的なバージョン(HTMLモック)を作る
  3. 必要なStateの洗い出し
    • コンポーネントに属する、変更される可能性のあるデータ/状態
    • 変更されないものはPropsで扱えばいいのでStateではない
  4. 洗い出したStateをどのコンポーネントが変更するべき、あるいは所有するべきなのか判断する
    • Stateをもとに動的にレンダリングする処理を追加していく
    • 単方向データフロー(親から子へのPropsの受け渡し、子が親を変更することは不可)を忘れずに
  5. 逆方向のデータフローの追加
    • 逆方向のデータフロー = 子の変化を親のStateに反映させる
    • やり方としては親の持つメソッドをコールバックとして子に渡す(onClickなどのイベントのコールバックとして)
    • 親が定義したやり方で変更(子が好き勝手はできない)

小さなものはトップダウンが向いてる。大きなものはボトムアップが向いてる

SPAにする場合

  • React Routerでルーティングを定義すると簡単にSPAが作れる
    • aタグだとサーバーにリクエストしに行くので、それではなくLinkコンポーネントで画面遷移する
  • SPAにせず画面遷移を完全にサーバーサイドで管理するならReact Routerは不要
  • コンポーネントをまたがってStateを共有する場合はRedux(Flux実装のデファクトスタンダード)を使う
    • アプリが小規模な場合はReduxなしで単純にPropsで引き回すなどの手段もあり。
    • Reduxはかなり冗長だがそれでもアプリの規模が大きくなると恩恵が大きい。TimeTravelDebuggingなど。
    • いったん書き方が分かれば難しくはない。めんどくさいだけで
  • リロードするとStateがクリアされる点に配慮が必要
    • 複数画面遷移のある処理において途中の画面でリロードされるケースなど

ルーティング

React Router
https://reacttraining.com/react-router/web/guides/quick-start

  • SwitchとRoute
    • Routeのpathが意図せずマッチしてしまうと描画したくないコンテンツが表示される
    • Switchを使うと上からマッチしていき、マッチしたところでそれより下のRouteは使われない
    • 最後にpathなしでルートへのRedirectを置いておくと、何もマッチしなかったときにそこにリダイレクトできる
    • exact={true}で完全マッチ(ないと/itemsは/itemsだけでなく/items/1にもマッチしてしまう)
  • SPAにおいてブラウザバックと画面の表示の整合性を取ってくれる
    • BrouserRouterを使うかRouterにhistoryオブジェクトを渡す

ReactのForm

TypeScript

  • 最初の印象
    • TSLintがうるさい。変更途中でエラー出し続けてうるさい
    • 型定義めんどい
  • でもこれハマったら数時間持ってかれてたかも、という変数の取り違えを「型が違うぞ」と未然に防いでくれたので元は取った感ある
  • 慣れるとだんだん気持ちよくなってきた
    • コンパイル時にエラーとなるものがVSCode上で分かるので、スクリプトを都度都度実行しながらエラーを修正する必要が無い
    • 補完が良く効く
    • 要するに効率が良い
  • ライブラリに型定義がない場合もエラーを出すため、使えないライブラリがあるというデメリット
    • 型定義があってもライブラリのバージョンアップ時に型定義が更新されなくてエラーになる場合もある
    • 自分で型定義を作ることは可能・・・だけどちょっとまだ自作できるほどの理解がない
    • 工数をかければ解決できるため少なくとも袋小路に陥ることはない

TSLint

  • エラーが出たらひっかかってるルールがエラーメッセージに出るので、その内容を調べて必要が不要か判断
    • 不要なようならルールを無効化。妥当なルールであればコードを修正
    • 最初のうちはルールをちょいちょいいじりながら開発
  • JSにもエラーを出してくるので時にjsRulesも設定する

jQueryについて

jQueryは悪くなくてjQueryで複雑なUIを作ろうとするのが悪い。

ReactとjQueryを混ぜるのは不可能ではないがあまり良くないらしい。特に理由が無ければ混ぜない方向で。

React初学者を待ち受けるハードル

  • チュートリアルから離れて実用的なものを作ろうとした時に複数の物事を並行して学んで行かなければならない
    • React
    • React Router
    • Redux
    • Recompose
    • Semantic UI ReactやMaterial UIなど 便利でよく使われるサードパーティコンポーネントの挙動
    • TypeScript: React公式のサンプルをTypeScriptに読み替え
  • 何でしくじってるのか切り分けがちょっと大変
    • 最初作るものからはReduxやRecomposeなどは外しておくのが無難
    • 今回ReactだけじゃなくてAWS Amplifyもいっしょにやってたのでなおさら混乱した
  • 何かをググると時間とともに陳腐化して参考にならない記事にあふれている
    • 記事の日付が新しくても古い情報を参考に書いてることがあるので油断ならない
    • 動かなくはないけど最新の推奨されるやり方とはすでに違っていたり
    • というか何が間違ってて何が正しいのか初学者には判断できない
  • とりあえず公式が一番
    • 幸いドキュメントが非常に充実している
    • しかし公式だけだと例が足りず理解できないこともある
    • 触って実際に動きを見ると腑に落ちるが、最初からドキュメントで把握するのは難しい
    • ある程度理解が進んだ後で公式ドキュメントをまた読むと良さげ
    • 公式一番に対してStack Overflowが次点
  • ハマリ事例
    • CheckboxのonChangeをハンドリングしようとするとevent.targetにlabelが入っててナニコレ?ってかんじなんだけど
    • Semantic UI React使ってるのでその仕様ですよ
    • onChangeに第一引数でlabelと第二引数でcheckboxが渡ってくる わからんではないけどマジか
    • コンポーネントごとにonChangeの引数変えるっていいのかなあ 普通なの?
  • しかし既存のコード資産が増える度にスピードが増していく感あり
    • 経験値を得るごとにリニアに強くなっていくRPGのイメージ

開発始めるとき

npx create-react-app my-react-app --scripts-version=react-scripts-ts
cd my-react-app
yarn add semantic-ui-css semantic-ui-react
yarn add react-router react-router-dom
yarn add -D @types/react-router @types/react-router-dom
yarn add react-redux
yarn add -D @types/react-redux
yarn add react-helmet
yarn add -D @types/react-helmet
yarn add -D typescript
yarn add -D typescript-fsa typescript-fsa-reducers
yarn add -D eslint tslint
yarn add -D stylelint stylelint-config-idiomatic-order
yarn add -D prettier prettier-stylelint stylelint-config-prettier
yarn add -D tslint-config-airbnb tslint-config-prettier tslint-plugin-prettier
yarn add -D lint-staged husky