はじめに🚀
はじめまして!YOUTRUSTでWebエンジニアをしている林(YOUTRUST)です。
先日誕生日を迎えたのですが、YOUTRUST上でたくさんのお祝いコメントをいただけて嬉しかったです! 社会人になってから祝われる機会が少なくなっていたのですが、こうやってお祝いコメントを送る場があるのは素晴らしいですね。 みなさんもよろしければYOUTRUST上でお祝いコメントを送ってみてください!
さて今回は、社内で開催されたReact公式ドキュメントの輪読会に参加しましたので、その内容と感想をご紹介していきます。
今回参加した輪読会について📚
同じくWebエンジニアの今井(YOUTRUST)が発起人となり、私含め有志のメンバー4人でReactの公式ドキュメントの輪読会を開催しました。
所要時間は45分で、最初の20分で各自担当のページを読み込み&Notionにまとめる、残りの20分間で一人5分ずつ学んだ内容を発表、最後の5分で質疑応答という形で行いました。
発表内容🗣️
今回は4人のメンバーそれぞれが自分が読みたいページを自由に選択。 各メンバーの担当箇所と学んだ内容を簡単にご紹介します。
1. React の流儀
この章では、Reactアプリケーション構築における体系的な思考プロセスについて解説されています。
ポイント💡
思考フロー
1.UIをコンポーネントに分割
モックアップのすべてのコンポーネントとサブコンポーネントを四角で囲んで、それぞれに名前を付けていく。
2.Reactで静的なバージョンを作成する
単にデータモデルからUIをレンダーする静的なバージョンを作成する。 まずはstateを使わずにUIを構築する。
3.最小限のstateを特定
stateとは、アプリが記憶する必要のある、変化するデータの最小限のセットのことであると考える。 最小限という部分が非常に重要であり、stateにすべきではない箇所を不用意にstate化しない。 以下に該当するものはstateではないため、state化しないようにする。
- 時間が経っても変わらないもの
- 親から props 経由で渡されるもの
- コンポーネント内にある既存の state や props に基づいて計算可能なデータ
4.stateの配置場所を決定
stateの配置場所の考え方
- 多くの場合、stateをその共通の親に直接置くことができる。
- stateを、その共通の親のさらに上にあるコンポーネントに置くこともできる。
- stateを所有するのに適切なコンポーネントが見つからない場合は、stateを保持するためだけの新しいコンポーネントを作成し、共通の親コンポーネントの階層の上のどこかに追加する。
頭でなんとなくわかっているようなことが改めて言語化されており、開発アプローチの選択基準が明確になりました。 今のところは既存機能の改修タスクがメインで新規に画面を作成することは少ないですが、今後そのような状況になった際にこの思考フローを参考にして実装していきます!
2. そのエフェクトは不要かも
この章では、useEffectの適切な使用方法と、不要なエフェクトを避けるためのガイドラインが示されています。
ポイント💡
エフェクトが不要な2つのケース
1.レンダーのためのデータ変換
Reactの処理順として、stateを更新すると、Reactはまず画面の表示内容を計算するためにコンポーネントの関数を呼び出す。 次に、Reactはこれらの変更をDOMに“コミット”して、画面を更新する。 その後、React はエフェクトを実行する。
ここでエフェクトの処理の中でstateをさらに更新してしまうと、上記のプロセス全体がやり直しになってしまう。
不要なレンダーを避けるために、コンポーネントのトップレベルですべてのデータを変換するようにする。
2.ユーザーイベントの処理
ユーザーイベントをエフェクトで対応してしまうと、エフェクトが実行される時点では、ユーザーが何をしたのか(どのボタンがクリックされたか等)がわからなくなってしまう。
そのため、通常は対応するイベントハンドラでユーザイベントを処理するべき。
実践的な代替手段
- 既存のpropsやstateから計算できるものは、stateに入れずレンダー中に計算する。
- コンポーネントツリー全体のstateをリセットするには、異なるkeyを渡す。
普段実装している中で気づいたらuseEffectを使ってしまっているという場面が多々あったので、改めてuseEffectの本来の役割・使用すべき場面等について学ぶことができ非常に勉強になりました。
特に、不要なケースでuseEffectを使用してしまうとパフォーマンスの悪化にもつながるため、レンダー中にpropsやstateから計算できないか、という視点を持つという点は今後の実装にも活かしていきます。
この章は文量が多いこともあり全てを時間内に読んで共有とまではいかなかったので、改めて自分でも読んで体系的に理解し直します!
3. エフェクトから依存値を取り除く
この章では、useEffectの依存配列を正しく管理し、リアクティブな値を適切に扱う方法が説明されています。
ポイント💡
「依存配列は自分で選ぶものではない」
エフェクトのコードで使用されるすべてのリアクティブな値は、依存値のリスト内で宣言されなければならない。依存配列は、その周囲にあるコードによって決定される。
- リアクティブな値:props、state、コンポーネント内で宣言された変数や関数
- リンターの役割:すべてのリアクティブな値が依存配列に含まれているかを確認
リンターを無視することの危険性
リンタをコメントでスキップすると、バグが発生するリスクが非常に高くなる。
よくあるバグ例:初期レンダー時の値を使用し続けてしまい、最新の状態が反映されない。
依存値を削除する正しいアプローチ
依存配列を変更したい場合は、まず周囲のコードを変更する。 依存値を削除するには、それが依存値である「必要がない」ことをリンターに「証明」する。
具体的には、
- コードをイベントハンドラに移動できないか検討
- 状態更新を更新関数に変更できないか確認
- エフェクトを分割できないか検討
依存配列にいれる値は自分で選択するものだと思い込んでいましたが、エフェクトのコードで使用されるすべてのリアクティブな値は依存値のリスト内で宣言されなければならず、依存配列はその周囲にあるコードによって決定される、ということを知り考えを改めるいい機会となりました。
この章は私が担当したのですが、発表時に「自分で選ぶものだと思っていた」というコメントを他の参加者からもいただき、自分だけでなく全員で知識のアップデートができた気がして輪読会の良さも実感しました!
4. カスタムフックでロジックを再利用する
この章では、カスタムHookによるロジック再利用の設計原則と実装のベストプラクティスが紹介されています。
ポイント💡
1. カスタムHookとは?
ロジックは共有するが、stateは共有しない。
Reactの組み込みHookを組み合わせ、useから始まる関数として自作したHook。複数コンポーネントで同じ処理を再利用し、UIとロジックを分離してテストや保守を楽にする。
2. 現場でよくある課題
- APIからデータ取得+ローディング+エラー処理を毎回書いている
- 同じフォーム入力ロジックをページごとにコピペしている
- ネットワーク状態やウィンドウサイズ監視など、UIと関係ない処理がコンポーネントを圧迫
3. カスタムHookを使うタイミング
「小さな重複は放置でOK」が基本方針
- あらゆる重複を消す必要はない
- useEffectを書く時は常に検討:外部システムとの同期は名前付きHookで表現する方が安全
4. 切り出しタイミングの基準
- 同じロジックを2回以上書いた(フェッチ、入力管理、イベント監視など)
- UIとロジックの境界が曖昧
- ロジックだけテストしたい
- 他の人や他画面で使いそう
5. 注意点
- 早すぎる抽象化は避ける(使う見込みがないなら作らない)
- 状態共有はできない(必要ならContextや外部状態管理)
- 命名は機能がわかるように(
useFetchUsers
,useDebouncedValue
など)
カスタムフックについて漠然と重複するロジックをまとめるという理解でしたが、使うタイミングが改めて言語化されており非常にわかりやすかったです。
現場でよくある課題を解決する手段としてカスタムHookは有効ですが、過度な抽象化や早すぎる抽象化は逆に複雑性を増すため、何でもかんでも抽象化すればいいということではないということが改めての学びとなりました。
輪読会の良かった点👍
複数のテーマを一度に学べる
4人がそれぞれ異なるテーマを担当することで、1つの輪読会で幅広い知識を獲得できました。
自分では選ばなかったかもしれないテーマも学べて、新たな視点を得られました。
アウトプット前提の学習効果
「発表する」という前提があることで、いつもより集中して読むことができました。
一人で読む時とは明らかに頭への入り方が違い、理解度が向上したと感じています。
最近はインプットに偏った学習が多くなっていたなと反省する機会にもなりましたので、今後は最低限自分だけのメモをにアウトプットするでもいいのでアウトプット前提のインプット学習ができるように心がけていきます!
質問しやすい環境
少人数(4人)での実施のため、堅すぎず質問しやすい雰囲気で進めることができました。
分からない部分をその場で確認でき、周辺知識含めた議論に発展できるのは、大きなメリットです。
わかったつもりの解消
普段「わかっているつもり」になっていたことを、改めて頭で理解することができました。
特に依存配列の管理やstateの設計原則など、基本的な概念について改めて体系的に学ぶことで新たな気づきがありました。
公式ドキュメントによる体系的学習
最近はClaude Codeをはじめとする生成AIの発達が凄まじいため、疑問点や知りたいことがあればまずAIに聞くという学習方法になりがちでした。
もちろんAIに聞くことのメリットも多いにあるのですが、一つの事柄に対してその周辺知識も含めて体系的に学ぶことができる公式ドキュメントや書籍の良さを改めて実感しました。
今後はAIとドキュメント・書籍それぞれの良さを活かしながら、両方を上手く活用して学習していきたいと思います。
改善点と今後の展望🤖
改善点
読む&まとめる時間が短く感じた一方で発表時間が結構余ったため、もう少し読む+まとめる時間の配分を増やしてもよさそうです。
また、最後に余った時間で質問タイムがあったのですが、少人数だからこそ聞きやすいことや普段業務で質問するほどでもないけど...みたいな質問ができ非常に有意義な時間であったため、今後は事前に読んできて質問・議論の時間をメインにした会があっても良いと思います。
今後の展望
今回の輪読会の中で設計やReduxについてもやりたいね、という話もあがったので次回は設計をテーマに技術書:「ソフトウェアアーキテクチャの基礎」の輪読会を予定しています。
私自身も日々の業務の中で適切な設計やReduxの処理のコードリーディングに苦戦することが多かったので、次回以降もぜひ参加したいと思いっています!
今後はこのような形で毎回異なったテーマで隔週で輪読会を開催していきたいと考えています。
まとめ💭
今回の輪読会を通じて、改めて以下のことを実感できました。
- アウトプット前提の学習効果の高さ
- チームでの学習における知識共有の価値
- AI以外の公式ドキュメントや書籍の体系的な理解の重要性
YOUTRUSTでは、このような自主的な学習活動を推進する文化があり、エンジニア同士が切磋琢磨しながら成長できる環境が整っています。
技術的な学習に積極的な方や、チームで学び合いたい方には、きっと良い環境だと思います。
YOUTRUSTではエンジニアを募集しておりますので、この環境で働きたい!と思った方や一緒にプロダクトをより良くしていきたいという方はぜひご応募ください!!