会場フォームのフックを早期 return の前に揃える (#372) - #481
Merged
Merged
Conversation
VenueFormPage は「編集権限なし」の早期 return より後ろで useState を 2つ呼んでいた。/venues/:id/edit を開いた直後は会場の取得が終わって いないので早期 return を通らず、応答が届いて権限なしと分かった瞬間に 通るようになる。その差し替えでフックの数が減るため、React が "Rendered fewer hooks than expected" を投げて画面が真っ白になる。 imageFailed と savedId を他のフックと同じ位置(関数の先頭)へ移し、 早期 return の手前に「ここから下でフックを足さない」と書き残した。 読み込み中→権限なしの差し替えを実際に描画するテストを足している (移動前はこのテストが上記の Error で落ちる)。 apps/web/src 全体を同じ形(早期 return より後ろのフック呼び出し)で 掃いたが、他には無かった。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SLkuubF8cHzSnnsv4fN9DA
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
再現
/venues/:id/editを、編集権限のない会場に対して開く。取得が終わるまではexisting.dataが undefined なので早期 return を通らずフォームが描画され、応答が届いて「権限なし」と分かった瞬間に早期 return を通るようになる。
早期 return より後ろに
useStateが2つあったため2回目の描画でフックが減り、React が
Rendered fewer hooks than expected. This may be caused by an accidental early return statement.を投げる。利用者には「権限がありません」の案内ではなく真っ白な画面(エラー境界まで巻き戻った画面)が出る。
直し方
imageFailedとsavedIdのuseStateを、他のフックと同じ関数の先頭へ移した(
apps/web/src/pages/VenueFormPage.tsx:49-52)。memo で包んだり return の位置を動かしたりはしていない。あわせて早期 return の手前に「ここから下でフックを足さない」
理由を書き残した(同
:74-75)。このページの残りも同じ観点で見たが、他に早期 return の後ろのフックは無く、
既存値ロードの
useEffectの依存[existing.data, isEdit]も過不足なかった。テストが噛むことの証明
apps/web/src/pages/VenueFormPage.hooks.test.tsxを追加した。読み込み中→権限なしの差し替えを実際に描画する。修正を
git stashで戻すと落ちる:修正を戻すと 2 件中 1 件が落ち、戻すのをやめると 2 件とも通る。
掃いた範囲
apps/web/srcの全.tsx(256 本)を「コンポーネント本体の早期 return より後ろのフック呼び出し」で掃いた。このファイル以外に該当は無し。
入れ子のコールバック内の return、
useStateの遅延初期化内の return、useEffectのクリーンアップ return は除外している。ついでに「if/for/try の中の直接のフック呼び出し」も掃いたが、こちらも 0 件。
確認
pnpm -r typecheckvitest run)run-tests.mjs)触ったファイルはいずれも 800 行未満(本体 325 行、テスト 128 行)。
Closes #372
🤖 Generated with Claude Code
https://claude.ai/code/session_01SLkuubF8cHzSnnsv4fN9DA