Q. ページにフォーカスを戻すと入力要素に入力していた内容が吹き飛ぶ場合がある
ページにフォーカスを戻すと入力要素に入力していた内容が吹き飛ぶ場合があるという相談を受けたため、その調査と対応についてまとめた。
調査ログ
次のように調査を行った。
- React DevToolsで現象を再現しながらProfilingを取った。
- 特定のコンポーネント以下で再レンダリングが確認できた。
- ネットワークタブと、当該コンポーネントのstateやpropsを調査した。
- ネットワークタブで同一のリクエストが連続して走っていることなどから、SWRのuseSWRを利用したカスタムフックが再レンダリングのトリガーになっていることがわかった。
- カスタムフックが再レンダリングを起こしている原因となっていそうな箇所を調査した。
- そのコンポーネント内では、カスタムフックの引数に変更は見られなかった。
- 子要素のuseEffect内で、引数となっているstateを更新している箇所が見つかった。
- 明白なアンチパターン
- useEffectを排除すると、入力要素の内容が吹き飛ぶ頻度が極端に減ったが解決はしなかった。
- 他にコード上は問題となる箇所が見受けられなかった。
- SWRが再レンダリングを抑制していないということは、レスポンスが変化しているのではないか?ということに気づいた。
- ネットワークタブを見た時点で気づくべきではある。
- レスポンスをいくつかJSONとして吐き出し比較すると、レスポンス内の配列の順序が安定していないことが分かった。
結論
特定のAPIのレスポンスが安定していないため、SWRが行う自動再検証で異なるレスポンスを返していると判定され、再レンダリングがトリガーされていた。
useEffectを修正して、頻度が減ったのは再検証の頻度が減少したため。