「React勉強するときに何見たらいいですか」と聞かれたときに紹介する文献集
react 全般
大体初めに「公式ドキュメントが充実しているのでそこからgetting startedするのが良いですよ」という話をしています
『りあクト!』シリーズもおすすめすることが多いです
- react, typescript, reduxに関して、それが導入されたモチベーションや効用に関して平易な言葉で解説されています
概念の整理に関してはics mediaの下の記事を紹介しています
-
https://ics.media/entry/200310/
- ややもすると古い記法で学んでしまいがちなので上の記事を読んで歴史的な流れを学んでねということが多いです
- ics mediaのreact系の記事はどれも面白いのでお勧めしています
- FrontEnd Study 5の基調講演も、reactに限らず宣言的FWの歴史的な流れを理解するのにとても勉強になりました
misc
- react kawaiiはかわいい
- (2021年4月の情報)最新のreact(確かv17)で使おうとしたらエラーが出た。ので16に落として使った
- https://qiita.com/e99h2121/items/1a4b59dad06aa4411ad7
redux
reactとreduxはセットではないですが、一緒に使われることも多いです。
- 最近のアプリであれば、(オレオレ状態管理も含む)何らかの状態管理をしていると思いますが、reduxの概念(flux)は理解するのに時間がかかるようです
- 確かにdispatch, action, reducerとかフロントエンドのほかの領域ではなじみのない言葉がいきなり出てきます。
- 非同期処理をデフォルトでサポートしていない(thunk, saga)を入れる必要があるというのも理解が難しい点です
- thunkが入るとおまじないのような書き方が増えてしまう(自分はこれをthunk文法と呼んでいます)点もなかなか悩ましいです
- 同期処理だけであれば理解するのはそこまで大変ではないので同期処理部分の状態管理はredux, 非同期処理の状態管理はuseSWR, react-queryを使うという手もありだと思います
- hooksだと非同期処理の結果はコンポーネントないに閉じてしまうので、コンポーネント間で管理するのが難しいように思えますが、API結果はこれらのライブラリの場合アプリ内でキャッシュされるので実質的に共有させることができる、ということもできます
- 多少reduxを振れたことがある人であればredux toolkitの使用をすすめたりもしています
- redux+reduxでよく使われるライブラリ、というライブラリです。日本語の解説もあります
- pros
- 記述量が格段に減るため、reduxのボイラープレートにつらさを感じた方にはおすすめです
- 公式の書き方をコピペするだけで、typescriptの型推論が完全に通る形で書けるので楽です
- cons
- 生のreduxと書き方が結構違う(省略されていたり、非同期処理がしれっと入っていたり)のでreduxを知らない人がreduxの概念を座学⇒redux toolkitで実践という流れで触ろうとすると「???」な状態になりがちです
- (createSliceを使う書き方だと特に)action, reducerの境界があいまいなので、reduxのflux構造との対応が見抜きにくくなっています
- 参考(非常に勉強になりました): https://zenn.dev/kazuma1989/articles/68c2339e056530
- 生のreduxと書き方が結構違う(省略されていたり、非同期処理がしれっと入っていたり)のでreduxを知らない人がreduxの概念を座学⇒redux toolkitで実践という流れで触ろうとすると「???」な状態になりがちです
react hooks
hooksの基本
hooksはシンプルな文法でかなり強力なので必ず勉強してね、と言っています。
-
もちろん最初はuseStateから
-
ある程度以上になった時はカスタムフックの作成と利用についても勉強してほしいと言っています。
- ロジックの隠蔽と再利用が容易になり、保守性と可読性がかなり上がるためです
- カスタムフックについての記事がどこかにあったはずだけど・・・
-
fireshipのyoutube: 英語だけどコンパクトでわかりやすいです
- というかfireshipのyoutube動画はどれもわかりやすいです
useSWR, react query etc
hooksの代表的な応用例としてuseSWR, react queryなどのAPIリクエストの管理ライブラリ(こういっていいのか?)があると思います。
reactのアプリを作る場合はこれらを導入することを強く推奨しています。
- APIリクエストなど非同期処理に伴う状態管理をいい感じにしてくれるライブラリです
- useSWR: https://swr.vercel.app/
- react query: https://react-query.tanstack.com/
- ほかにもapollo client, RTK queryなどもこのカテゴリとされます
- react queryが比較表出してバチバチ戦っています(笑): https://react-query.tanstack.com/comparison
- 今まではAPIリクエストをいちいちreduxで管理していたので、APIリクエストを投げるたびに「APIリクエストしたからisLoading=trueにして」、「レスポンスがエラーになったのでstate.isErrorをtrue」にして、、、と書いていました。
- 記述量が多い=開発コストがかかる
- その分、バグも多くなる
- useEffectが無限ループに入って「あ、あぁ・・・」となる(経験談)
- キャッシュとかポーリングとかの機能も自前で作る必要がある
- 記述量が多い=開発コストがかかる
- この辺りの負をuseSWRやreact queryは鮮やかに解決してくれます
- 導入は簡単で、どちらも公式ドキュメントが親切に書かれています
- 少なくとも「これどうやって実装するか」と思ったことはたいてい実装されている
- ただ、hooksの一種なのでコンポーネントのtop level以外で宣言すると一発でエラーになるので注意が必要です
- 最初のころは「バリデーションをして、それに通ったらuseSWRでクエリを投げて、、、」みたいな書き方をして何回もエラーになりました・・・。
- これを注意してくれるeslintの何かがあった気がしますが忘れました
- 導入は簡単で、どちらも公式ドキュメントが親切に書かれています
概念や大まかな挙動は下の記事を見て勉強しました
-
https://panda-program.com/posts/useswr
- プログラミングするパンダさんの記事はとても勉強になるので(ほぼ)すべて読んでいます
- redux toolkitの話とか, https://panda-program.com/posts/redux-toolkit-library
- プログラミングするパンダさんの記事はとても勉強になるので(ほぼ)すべて読んでいます
-
react queryはこのzennの記事で勉強しました: https://zenn.dev/brachio_takumi/articles/20210226-react-query
-
useSWRは豊富なオプションが提供されているので、「何が使えるかな~」と探すときは下の記事を見ています
-
react queryもとても書きやすいと感じます
-
これらのライブラリはuseEffectと同様「キーとなる変数を監視して、それが変更されたらAPIリクエストをする」という流れなので、自動でクエリが投げられます
- 最初のころは「API投げるタイミングが自分で管理できないので気持ち悪い」、「クエリを投げるタイミングはonClickイベントで発行しないと気持ち悪い」みたいなことを思っていました
- 使っていくうちに、「宣言的なFWを使っているのだから、ページの状態も宣言的に作りたくて、クエリが自動で投げられる方が宣言的では?」というように感じました。この気づきがあってからuseSWRとかをうまく使えるようになったような気がします。
-
どっちもAPIの結果をアプリ内でグローバルにキャッシュしてくれます
- react queryはQueryClientProviderで囲んだ範囲がそれになるなのかな(未確認): https://react-query.tanstack.com/reference/QueryClientProvider
- QueryClientProviderなしだとエラーになる
- useSWRはnextで使っていればビルド時にかってに仕込んでくれるのでしょうか(未確認)
- react queryはQueryClientProviderで囲んだ範囲がそれになるなのかな(未確認): https://react-query.tanstack.com/reference/QueryClientProvider
Next.js
Nextjsは最近(2021時点で)すごく人気で勉強になる記事がたくさんあります。
- https://qiita.com/thesugar/items/01896c1faa8241e6b1bc
- https://qiita.com/jagaapple/items/faf125e28f8c2860269c
一方で、変化や流れも速く、キャッチアップが大変な側面もあります
-
いつの間にかnext.config.jsに何も書かなくても良しなに設定してくれるようになった
- tsファイルがあったら自動でtsconfig作ってくれるようになったり
- 書いていたら、バージョンアップ時にむしろバグってしまったり(経験談)
-
getInitialPropsからgetServerSideProps, getStaticPropsへの移行とか
-
公式ドキュメントがとても分かりやすいので、nextに初めて触る方にはこれを一周することをお勧めしています
-
nextはgithubで提供されているexamplesが非常に充実しているので「Nextと〇〇(例: typescript, redux, ...)を組み合わせたい時どうするの?」と聞かれたときは「examplesからcloneして試してみてね」ということが多いです
-
reactのアプリを作るには必須ではないが、以下のことを非常に簡単にできるので素振りでアプリを作るときはほぼ毎回使っています
- ルーティング
- SSR
- 難読化・コード分割
Recoil
facebook製の最近出てきた状態管理ライブラリです。
-
最近試しました。
- 1ページ、5,6本のAPIを埋め込むような画面で
- pros
- atomとselector(derived state)に分けた設計が容易にできるので画面の状態を宣言的に作ることができそうです
- シンプルに(=特に気を付けないで)作っても再レンダリングが非常に抑制されたものが作れるのでパフォーマンスが高いものが作れそうです
- 必要なatomやselectorを必要な場所にだけ呼び出す、という書き方が自然にできるのでpropsの受け渡しがかなり減るのも一つの理由かと思います
- 無論、React.useMemo, React.useCallbackなどを使って再レンダリングを抑制することも可能ですが、記述量が多くなりがちなのとバグが起こりやすくなってしまうので少し敬遠していました。
- 参考(これらの記事の内容と書いた方を批判したり貶めたりする意図はありません)
- 無論、React.useMemo, React.useCallbackなどを使って再レンダリングを抑制することも可能ですが、記述量が多くなりがちなのとバグが起こりやすくなってしまうので少し敬遠していました。
- 必要なatomやselectorを必要な場所にだけ呼び出す、という書き方が自然にできるのでpropsの受け渡しがかなり減るのも一つの理由かと思います
- cons
- カスタムフックで隠蔽することが前提になっているので、reactアプリを初めて触る人には敷居が高いかなと思いました。
- atomを無秩序に作ってしまうとその管理が大変そうです
- 特に「似たような状態を作らない」「このatomはどこで管理するのか」をチームメンバーが迷いなく遂行できるためには、ディレクトリ戦略をうまく考えないといけないなと思いました
- 「論理的に関係しないと思っていたatomが開発途中で実は関係する」と分かった時のリファクタリングも大変そう
- reduxならある程度大きい粒度でstateが分割されているのでまだリファクタリングは大変ではないように思います
- (2021/05/03時点で)devtoolsが(まだ)ない(多分)
- redux devtoolsのようにアクション発行の時系列がわかったり、その時点での状態のスナップショットがわかったりするのが恋しいです
- 何となく自分は状態を「A. 隣り合う2,3コンポーネント内で完結するもの」、「B. ページ内で使われるもの」、「C. アプリ全体で使われるもの」の3階層に分類していて、今までは「AはuseStateをはじめとするhooks, B, Cはredux」というように分けていたいのですが、reduxだとBのようなほかのページで参照されない状態を
-
登場直後に出た記事(typescriptで有名なuhyoさんの記事)
- https://blog.uhy.ooo/entry/2020-05-16/recoil-first-impression/
- Line証券やNature Remoではすでに(少なくとも2021年4月現在)実践投入されているらしいです
-
有名なmizchiさんの記事: https://mizchi.dev/study-recoil
-
UIT insideでも取り上げられていました
- https://uit-inside.linecorp.com/episode/49
- 「recoil使うならカスタムフックを使って」という話に非常にうなずきました
- 通常のカスタムフックと違ってコンポーネント間で状態とロジックを共有できるので、「ロジックは同じだけどDOM空間的に離れている要素」の間で簡単にロジックを共有できるのがうれしいなと感じます。
- モーダルの状態やイベントの管理とか、画面全体を支配する変数(記事詳細ページの記事IDとか)の管理をさくっとかけるのもうれしいです
reoiclで非同期処理
- ここら辺を見た
recoilでSSR
- ここらへんかなぁ
- getXXPropsで取得した値をinitializeStateに突っ込むとか
- atomの初期化はこれで簡単にできるけどselectorの値はどうするんだろう
- 例えばSSR時にAPIリクエストして、APIレスポンスの値を突っ込むけどAPIレスポンスの値はselectorにあるとか
- selectorのsetを使うのかな?
- 例えばSSR時にAPIリクエストして、APIレスポンスの値を突っ込むけどAPIレスポンスの値はselectorにあるとか
困ったこと
- recoil + nextjsで試したら非同期処理のErrorBoundaryがエラーをキャッチしてくれなかった
- これと同じエラー(だと思う)
- https://github.com/facebookexperimental/Recoil/issues/722
- https://github.com/facebookexperimental/Recoil/issues/722
- それどころかSuspenseもちゃんと動いていなかった感じがする
- これと同じエラー(原因が同じかは不明): https://github.com/vercel/next.js/issues/22508
- 参考にした記事
- これと同じエラー(だと思う)