0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Reactのデバッグで役立つ5つのTipsと、僕が昔ハマった失敗談

0
Posted at

なぜデバッグって難しいのだろう

新人時代、とあるバグを見つけるのに丸一週間かかった記憶があります。最初に試したのは「とりあements problem」でしたが、どこが悪いのかわからず、結局原因不明のまま放置していました。あの頃の自分に、「とりement problemだけじゃなくて、ちゃんとコードを追えばわかるのに」と声をかけたいです。Reactは「宣言的」な記述方法をとるため、期待通りに動作しないとき、どこが変わったのかを追うのが少し手間取ります。特にバグが小さいときは、自分が何をしたかを振り返らずに症状だけを見てしまいます。「ここがおかしい気がする」と表面的な部分だけで終わってしまいがちです。

✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨

最新ツール・トレンド情報をずんだもん×めたんが解説するYouTubeチャンネルを運営しています!
いいね、チャンネル登録してもらえると嬉しいです🙇‍♂️


ハジメル.dev: https://hajimeru-dev.vercel.app/

「ひとりで続けるのは難しい」「何から学べばいいか分からない」という方向けに、
プログラミングのマンツーマンレッスンサービス「ハジメル.dev」も運営しています。
未経験OK・オンライン完結・月額制/違約金なしなので、気軽に無料相談してみてください🙇‍♂️


海外テックニュースを追いたいけど、英語や情報量の多さで大変…という方向けに、
Hacker News の話題を日本語でサクッと追える「HackerNews 日本語まとめ & AI要約」
を個人開発しました!
技術トレンド収集に使ってもらえると嬉しいです🔥🙇‍♂️
→ HackerNews 日本語まとめ & AI要約: https://hn-matome-2ht.pages.dev/


「ニャンパイアサバイバー」というヴァンパイアサバイバーリスペクトのゲームを作成しました!
もしよろしければ遊んで頂けると嬉しいです😭


習い事教室の先生向けに、SNS 投稿・生徒募集・保護者通知の文章を AI で生成する Web サービス「おしらせAI」を個人開発しました。Next.js + Supabase + LLM で構成しており、無料で月 10 回まで試用できます。よければ触ってみてください。

→ おしらせAI: https://oshirase-ai.vercel.app/


言いたいことがうまく伝わらない…という方向けに、会話の言い方を添削する「伝え方ラボ」を開発中です。
場面を選んで自分の言葉で返すと、何が伝わっていないかの指摘と、そのまま使える言い換えが返ってきます。
ChatGPT に相談すると褒めから入って直すべきところが残りがちなので、指摘側に振り切りました。
現在は公開時にお知らせするメール登録のみ受付中です🙇‍♂️

→ 伝え方ラボ: https://tsutaekata-lab.pages.dev/

✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨

第一に大切なことは、根本原因を理解すること

僕が初めてつまずいたのは、useStateの初期化値が意図通りにならなかったときでした。計算結果をstateに保存しようと思って、calcValue()関数を定義したのですが、呼び出された瞬間にstateが更新されるため、calcValue()の計算結果自体は反映されませんでした。calcValue()関数が実行されるたびに、stateの値が毎回計算されてしまうのです。つまり、calcValue()の呼び出し側と、calcValue()内で更新するstateが別々に行われていました。

import { useState } from 'react';

function App() {
  const [value, setValue] = useState(null);

  const calcValue = () => {
    setValue(42); // 呼び出し側で更新
  };

  return <button onClick={calcValue}>計算</button>;
}

このコードは単純に見えますが、buttonのonClickでcalcValue()を呼び出すたびにvalueが42に更新されます。setterを呼ぶたびにstateが更新されるため、計算結果が反映されません。解決策は、stateに計算結果を保存するのではなく、calcValue()内でcalcValueの計算結果を直接使用するか、useEffectでcalcValue()の結果をstateに反映させるかのいず方式です。前者ならcalcValue()を呼ぶたびにvalueが変わりますし、後者ならcalcValue()の呼び出しとstateの更新が分離されます。

第二に、エラーメッセージを侮らないこと

僕は「エラーメッセージが出ていても、とりあements problemで解決できる」と思い込んでいました。しかし、あるときuseEffect内でAPIコールバックを呼び出すコードを書いたところ、callback内でuseStateのsetterを呼び出してしまいました。React Hooksのルールにより、component内部で副作用を扱う際はuseEffectなどの特殊構文を使用しなければなりません。setterを直接呼び出すと「Invalid useEffect callback return value」というエラーが出ました。このエラーは「useEffectの戻り値が関数でない」ことを指摘しています。setterを呼び出さないように修正することで、症状はすぐに改善しました。エラーメッセージは英語で書かれていることが多いですが、そのまま翻訳するのではなく、文脈を汲み取って原因を特定する必要があります。

第三に、開発環境を整えること

僕が昔、「とりements problem」のインストラクターとして活躍してくれたのは、VS Codeでしたが、エディタ上部の「Run and Debug」パネルを有効活用していませんでした。デバッグ用のブレクトークポイントを設定し、変数の値を確認するだけで、数千行あるコードの中からバグの简を一発で見つけられるようになります。また、React DevToolsというブラ拡張機能を使うと、コンポーンスpecificなプロセスpecificな状態やpropsを確認できます。僕は最初からDevToolsを使っていたら、前述のuseStateの初期化値のバグももっと早く発見できたはずです。開発環境は「とりements problem」だけではなく、デバッグツールも含めて、最初から丁に整えることが重要です。

第四に、小さな変更を積み重ねること

僕は一度に全体を書き直す癖がありました。バグが発生している部分を一括で修正しようとして、かえって複雑になってしまうことが多かったです。修正案は、特定の機能単位で部分的に修正し、徐々に全体を修正していくことです。例えば、useStateの初期化値をnullにしたあと、徐々に適切な初期値に変更していきます。この方法は時間がかかりますが、原因简が明確になりやすく、後で修正する範囲が限定されます。小さな変更を繈的に行うことで、バグの修正が安定しやすくなります。

第五に、他人のコードを読むこと

僕はチーム内でコードレビューを依頼するのが苦手でした。しかし、ある案件でバグを発見した後、先輩エンナーが作成した同様の機能のコードを見せてもらい、useCallbackとuseMemoの使い方を学びました。useCallbackはcallbackの参照を保持し、不要な再描画を防ぐことができます。useMemoは計算結果をキャッシュし、再計算を防ぐことができます。これらのテクニックは、バグの修正だけではなく、パフォーマンスの向上にも役立ちます。他人のコードを読むことで、自分の視野が広がり、新しい気づきを得ることができます。

まとめ

Reactのデバッグは、とりements problemだけではなく、根本原因の理解、エラーメッセージの読み取り、開発環境の整備、小さな変更の積み重ね、他人のコードの読むといった地道な努力が必要です。僕は最初つまずいたuseStateの初期化値のバグも、DevToolsと修正案で解決しました。初心者はつまずきやすいですが、根気よく修正していくうちに、バグの修正力も身につきます。少し先を歩いている先輩として、皆さんにも地道な努力を推埋します。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?