Skip to content

Conversation

@aDaisukeHirano
Copy link
Contributor

@aDaisukeHirano aDaisukeHirano commented Dec 25, 2024

更新内容

React研修資料で改善した方が良さそうなところにコメントをしました。
間違っているコメントやもっとよい改善方法が見つかると思うので、レビューをいただいたあとに清書する予定です。

コメントの修正方針で良いか悪いかだけでも、コメントをお願いします。

--- 2025/03/13 追記 ---

1章〜7章までの範囲外でのコメントが大量に発生してしまったため、こちらは別途 PR を出して対応予定です。
そのため、本 PR では8章〜15章(08_state.md ~ 15_advanced.md)までの範囲を対象とします。

--- 2025/03/23 追記 ---

1章〜7章の修正を別のPRで出すことになっていたのですが、このPRにまとめることになりました。

注意事項

  • 別PRでprettierの導入をしようと思っているので、フォーマットに関する指摘はしていただかなくて大丈夫です。(3/25 追記)

変更内容のまとめ (2025/03/24 追記)

1章 TSXを学ぶ

  • 「TSX」を「JSX」に変更
  • コンポーネントについての説明を削除 (3章の冒頭に移動)
    • 3章で説明しているため
  • その他、内容を大きく変えずにわかりやすい文章に改善

2章 要素のレンダー

  • DOMの説明を追加
  • 「リアルDOM」を「実DOM」に名称変更
  • 仮想DOMの差分検出を表す図を差し替え
  • DOMの差分のみが反映されることを表すサンプルコードを「秒刻みで動く時計」から「掛け算の計算」に変更
    • 「秒刻みで動く時計」のサンプルコードはコンポーネントを再マウントしており、全体が更新されるようになっていたため修正。

3章 コンポーネントとprops

  • 1章で書かれていたコンポーネントの説明を導入の説明に追加
  • コンポーネント名をUpperCamelCaseで書かないと動作しないことを追記
  • コンポーネント分割の方針として「Bulletproof React」を追加
  • その他の軽微な修正

4章 イベント処理

  • 内容を大きく変えずにわかりやすい文章に改善

5章

  • 軽微な修正

6章 リストとkey

  • mapのkeyの設定ミスによる不具合について追記
  • keyとして指定できる型を追記

7章 Reactのライフサイクル

  • 「状態」という見出しを「ライフサイクル」と「段階」に分離
  • レンダーフェーズとコミットフェーズの説明を修正
  • useEffectとuseRefの説明を修正
  • useImperativeHandleとuseDebugValueの説明を削除
  • React19ではhooksが17個存在することを追記
  • その他の軽微な修正

8章 state

  • 純粋関数に関する説明を削除
  • useStateは「インタラクティブに画面を更新する機能を実現するためにAPI」という説明とする。
  • [状態変数, 状態変更関数] = useState(状態変数の初期値)[現在のstate, 状態更新関数] = useState(状態の初期値)に変更
  • hooksは関数コンポーネントのトップレベルでのみ宣言可能という説明を削除
    • 10章で説明されるため
  • 「stateにするのはprimitiveな値を推奨し、objectやarrayの場合はuseReducerを使うべき」という説明を削除
    • objectやarrayをstateにするのは非推奨ではないため。むしろ、state 構造の選択で、関連するstateはobjectにまとめることが推奨されている。
  • stateが更新されてから画面が更新されるまでの流れを表す図を追加
  • setState(prevState => prevState + 1)のように、状態更新関数に関数を渡すこともできることを説明するための見出しを追加

9章 state の更新ロジックを抽出する

  • 章のタイトルを「複数のstateをまとめる」から「stateの更新ロジックを抽出する」に変更
    • useReducerの役割は、複数のstateをまとめることではなく、stateの更新ロジックをコンポーネントの外にreducer関数として切り出すことであるため。
  • 章タイトルの変更と合わせて、useReducer導入の説明を修正。useReducerを使うタイミングは「更新ロジックが複雑な場合」として、その例として「stateの更新方法が複数あるケース」を挙げている。
  • useStateではなくuseReducerを使うことを考慮するケースを変更。
  • 「reducer」の由来が、Array.protetype.reduce()であることを説明する見出しを追加。詳細までは説明せず、公式Documentに飛ばす形にしている。

10章 Hooksのルール

  • 軽微な修正

11章 値の同一性を理解する

  • useCallbackに関する「値の同一性を考慮していない実装の例」「useCallbackの導入」「値の同一性を考慮した実装の例」の見出しを削除
    • useCallbackはReact.memoと合わせて説明した方がわかりやすいと思ったため14章に移動
  • 「メモ化の不要の関数オブジェクト」については、14章で新しく追加した「(optional) 依存配列に設定するのは「リアクティブ」な値」の中で扱っている。

12章 副作用を実行する

  • 副作用の説明が非純粋関数の説明になっていたので、副作用の説明に修正
  • useStateが副作用であるという旨の記載を削除
  • 副作用を「ユーザーのアクションがトリガーとなる副作用」と「画面表示がトリガーとなる副作用」に分類をした上で、前者はイベントハンドラ、後者を実装する際にuseEffectを使うという説明に変更
  • React公式に倣って「画面表示がトリガーとなる副作用」を「エフェクト」と名付け、このドキュメントで「エフェクト」の意味で使われている「副作用」の名称を「エフェクト」に変更。
  • 「依存配列に入れる値を調整してエフェクトの実行タイミングをコントロールする」と捉えられる説明を削除。依存配列にはESlintに従って全ての依存値を設定するものであることを追記。
  • 「クリーンナップを必要としない副作用」と「クリーンナップを必要とする副作用」という分類を削除。クリーンナップが必要である場合は記述するという説明に変更。
  • useEffectの実行タイミングを説明するライフサイクルの図を差し替え。セットアップとクリーンナップが実行されるタイミングを明確にする狙い。
  • 課題12-1をuseEffectとSuspenseを使って実装する課題からuseStateとuseEffectを使って実装する課題に変更。
    • 模範解答を見ると、Suspenseの課題というよりかはtoTask関数を実装する課題のようになっていて、身につけて欲しい内容ではないと思ったため。
    • Suspense導入前の問題に戻す形になっており、模範解答はReact研修 課題解答例 - 2023にあるため、課題内容変更によって模範解答を新規作成する必要はありません。
  • Suspenseの説明で挙げられていたサンプルコードが動作しなかったため、React.useを使うコードに修正。それに伴い、Suspenseの説明も修正
    • サンプルコードが動作しなかったことについて、dataをuseRefで管理していたため、dataを更新しても再レンダリングがされず、promiseが解決しても何も表示されないままになっていました。では、useStateを使えば良さそうですがそれでも画面は更新されません。詳細は、「ReactのSuspense対応非同期処理を手書きするハンズオン」の「useStateを使ってみる(失敗例)」で説明されています。結論として、コンポーネントの外部にデータを持つ必要があります。
  • Promiseが「完了する」という表現を「解決する」に変更
  • 「Suspense 対応のデータソース」の見出しを追加
  • 課題12-2を追加。課題内容は、課題12-1をSuspenseとuseを使って書き直すこと。

13章 その他のHooks関数

  • useRefで宣言した値を画面表示で使ってはいけないという注意書きを追加
  • 軽微な修正

14章 描画パフォーマンスの最適化

  • React.memoの説明をuseCallbackとuseMemoの説明と同じ形式になるように修正
  • useCallbackの見出しを追加 (11章から移動)
  • 「React.memo と useCallback を使ったパフォーマンス改善例」の見出しを追加
    • サンプルコードも追加。レンダーが重いコンポーネントをmemo化し、その重いコンポーネントのpropsの関数をuseCallbackでメモ化して、パフォーマンスを改善している。
  • useMemoの見出しを追加
    • もともとuseMemoは取り上げられていなかったが、React.memoとuseCallbackを取り上げるならuseMemoも取り上げるのが自然だと思ったため。
    • 公式Document useMemoを参考にして、最低限の文法のみ説明。
    • useMemoを使った改善のサンプルコードを追加
  • 「React Compiler」の見出しを追加
  • 「依存配列に設定するのは「リアクティブ」な値」の見出しを追加
    • 「useEffect、useCallback、useMemoの第2引数は、第1引数の関数が依存する値を設定する」というのが正確性に欠ける説明であるため、補足説明。
    • 11章で「関数コンポーネントのスコープ外で定義された関数はメモ化不要」という説明よりも、「関数コンポーネントのスコープ外で定義された関数はリアクティブでない」のほうがよいと思った。

why_need_react

  • Nextjsの説明を修正
    • PagesRouterに限らずAppRouterにも当てはまる説明のため、「PagesRouter」という文言を削除。

その他

  • 新しく作った課題12-2でReact19のuseが使う必要があったため、exerciseのReactのバージョンを19に更新。それに伴い、storybookのバージョンも更新。


計算が終わると、リアル DOM は実際に変更されたものだけが更新されます。

// "実際に変更されたもの"という文言が少し気になるので
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

「算出した、『実際に変更のある部分』のみ、リアル DOM を更新します。」

という表現はどうでしょう。

// 「コンポーネント内のDOM要素の参照を取得する」は誤解を与えるため避けたいです。React公式Docには、「useRef は、レンダー時には不要な値を参照するための React フックです。」と書かれており、「レンダー時には不要な値を参照する」としたいです。
| `useImperativeHandle` | **** コンポーネント内のDOM要素の参照を取得する |
| `useDebugValue` | React DevTools でカスタムフックのラベルを表示する |
// useSyncExternalStoreやuseTransitionなど、React18,19で追加されたHooksを追加するか考えたいです。個人的には、初学者をターゲットとしているので追加しなくても良いかなと思いました。追加しないのであれば、使用頻度が低いuseImperativeHandleとuseDebugValueは削除して良いのかなと思いました。
Copy link
Contributor

@aTomohiroIto aTomohiroIto Dec 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

初学者向けに内容を小さくまとめるなら、useCallback、useMemo も同様に外して良いのでは、と思いました。
いずれ自動最適化が働くことを見込んでいます。

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

useCallback, useMemo は実案件での使用頻度が高いので残した方が良いです。
useImperativeHandleuseDebugValue は僕は見たこと無いので削除して良いでしょう。
新しい hooks についてはどっちでも良いと思います。講師次第ですが、口頭で紹介するくらいがちょうどいいのかも?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

useCallback, useMemoに関しては同じ理由で自分も残したいです。

一方、`state`は、コンポーネント自身が持つ情報で、かつ、書き換えができます。
// レンダリング中は書き換えは出来ないですし、書き換えるにしてもmutableな変更は出来ないので、「書き換えができます」とは書きたくないです。

関数型言語では、**純粋関数****不純関数** という用語があります。
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(今回のPRのスコープ外ですが)「不純関数」ではなく「非純粋関数」ですね。

Comment on lines 18 to 20
// stateは副作用ですが、immutableなので、ある意味「引数のようなもの」と考えることもできます。
公式Docの[純粋性が重要である理由](https://ja.react.dev/reference/rules/components-and-hooks-must-be-pure#why-does-purity-matter) には、「コンポーネントの入力とは props と state とコンテクスト。フックの入力とはその引数。」ともあります。
stateを副作用の代表として取り上げたくないです。
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

state を引数として解釈すれば確かにそうなりますが、「拡大解釈し過ぎでは?」とも思います。

普通に解釈すると、関数の引数である props のみが引数であり、引数が同じであれば結果が同じ(参照透過性)というのが純粋であるための必要条件なので、propsが同じでもstateが変わると返り値が変わるというのは純粋ではないです。

あまりこういったおかしな解釈を広めたくないという思いはありますが、Reactの公式ドキュメントと矛盾するのも良くないですね。純粋云々の記述自体削除してしまったほうが良いと思います。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

そうですね

まるまる消してしまってもよいと思いますし、「useStateは副作用か」という見出しを作って、一般的な純粋関数の定義に沿った説明と、公式ドキュメントの説明を両方載せてもよいのかなと思いました。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ボリュームの関係で削除することにしました。

Comment on lines 37 to 40
stateは、レンダリング間で値を保持したいもの、かつ、値が書き変わったときに際レンダリングしたい値を保持するもの
refは、レンダリング間で値を保持したいもの、かつ、値が書き変わったときに際レンダリングしたくない値を保持するもの

と説明したいです。
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

良い説明だと思います。

@aDaisukeHirano
Copy link
Contributor Author

aDaisukeHirano commented Jan 16, 2025

web_frontend定例で、webfrontend_specialistチーム全員をレビュアーにすることにしました。

お忙しいところ恐縮ですが、お時間ある方、レビューをよろしくお願いします。

基本的には、下記の命名規則を使うことになります。

- コンポーネント名は、「**upper camel case**」(e.g. CamelCase)
// 命名規則ではなくて、守らなければならないReactのルールということを書いておきたいです。[関数を定義する](https://ja.react.dev/learn/your-first-component#step-2-define-the-function)
Copy link
Contributor

@aTomohiroIto aTomohiroIto Jan 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

規則を解説する章なので、規則であり必ず守る、と明示する立場をとりたいです。
開発案件のコーディングルール、原則的な命名規則、Reactのコンパイル仕様、について、いずれも守らなければ(それぞれ別種の)トラブルになるので、その序列は重要でないという考えです。

例文 :

開発案件はコーディングルールがあらかじめ決められているので、そのルールに従います。

Reactでは下記の命名規則を使います。

  • コンポーネント名は、「upper camel case」(e.g. CamelCase) ※落とし穴
    ...

判断に迷うときは、JS/TSの慣習に従ってください。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

はい、補足説明の形で「落とし穴」のリンクを記載する形にしますね。

@aDaisukeHirano
Copy link
Contributor Author

修正が完了したため、再度レビュー依頼をしました。
よろしくお願いします。


> const f2 = f0
> Object.is(f0, f2)
true
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(optional) Object.is(NaN, NaN) の例があったほうが === との違いがわかって良いと思いますが、あまり細かいところに踏み込まないつもりであればこのままでも構いません。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

面白い内容だと思ったのですが、この章で学んでほしいことではないと思ったので、取り入れないことにしました。

講義で余裕があったら話題に出してみようと思います。

@aDaisukeHirano aDaisukeHirano requested a review from SekiT March 25, 2025 11:23
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

08_multi_state.svg も透過されているので背景を白にしておいてください。

また、できれば画像の雰囲気を他のものと揃えたいですが、それは optional で良いです。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

そもそも、この図がなくても十分複数のstateが扱えることがわかるので、削除した方がよいと思いました。
伊藤くんはどう思いますか?

もし差し替えるなら、こんな感じにしようと思っています。
image

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

代替案まで書いてくれてありがとうございます。
はい、なくても伝わるので削除して構わないと思います。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

削除しました。

4403291

Copy link

@SekiT SekiT left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

僕からはOKです。

Copy link
Contributor

@aFumihiroSaito aFumihiroSaito left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ご対応頂きありがとうございます。
コメント部分の対応はお任せ致します。

- 任意の赤色の物の名前, 緑色の物の名前, 青色の物の名前を TSX 内に追加
- それぞれが赤色, 青色, 緑色となるようにスタイルを指定
- 任意の赤色の物の名前緑色の物の名前青色の物の名前を JSX 内に追加
- それぞれが赤色、緑色、 青色となるようにスタイルを指定
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- それぞれが赤色、緑色、 青色となるようにスタイルを指定
- それぞれが赤色、緑色、青色となるようにスタイルを指定

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

format

こちらで修正しました。


![Hooks Lifecycle](./07_hooks_lifecycle.svg)
ここで紹介したもの以外にもさまざまな Hooks が用意されており、 React 19 では全部で17個存在します。
なかでも利用頻度の高い API は、 `useState``useEffect``useReducer``useCallback` の4つです。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Optional]
useEffect は極力使わないように、という点を考慮すると、利用頻度の高い対象から外しても良いかもですね。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

他のhooksに比べると使用頻度が高いので、残すことにします。

「極力使わないようにする」というのは、「誤った使い方をしない」という意味で解釈しています。

# React.memo と useCallback を使ったパフォーマンス改善例
レンダー中に重い計算をしている`Button` コンポーネントの再レンダリング回数を最小限にすることを目標とします。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
レンダー中に重い計算をしている`Button` コンポーネントの再レンダリング回数を最小限にすることを目標とします。
レンダー中に重い計算をしている `Button` コンポーネントの再レンダリング回数を最小限にすることを目標とします。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

format

こちらで修正しました。

// * それぞれが赤色, 青色, 緑色となるようにスタイルを指定
// * 並びや位置関係、厳密に物の色が正しいかどうかは不問
// * 任意の赤色の物の名前緑色の物の名前青色の物の名前を JSX 内に追加
// * それぞれが赤色、緑色、 青色となるようにスタイルを指定
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// * それぞれが赤色、緑色、 青色となるようにスタイルを指定
// * それぞれが赤色、緑色、青色となるようにスタイルを指定

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

format

こちらで修正しました。

@aDaisukeHirano
Copy link
Contributor Author

たくさんのレビューありがとうございます。

マージします。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants