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?

子コンポーネントのPATCH処理時に親が再レンダリングしてしまう

Last updated at Posted at 2025-05-25

概要

React + Vite + json-server を使った開発環境で、子コンポーネントでPATCH処理を実行すると親コンポーネントが予期せず再レンダリングされる現象に遭遇しました。

子コンポーネントは親の状態を一切更新していないし、何をトリガーに再レンダリングされるのか分からずハマってしまいました。

結果的には ViteのHMR(Hot Module Replacement) が原因でした。

現象

子コンポーネントでjson-serverにPATCH リクエストを送信すると、親コンポーネントが即時再レンダリングされる。

TaskList.tsx(親コンポーネント)
const fetchTasks = async (): Promise<Task[]> => {
  console.log("APIからタスクを取得中...");
  const response = await fetch("http://localhost:3000/tasks");
  return response.json();
};

const fetchTasksPromise = fetchTasks();

export function TaskList() {
  const tasks = use(fetchTasksPromise);

  return (
    // 〜省略〜
      {tasks.map((task) => {
        return <TaskItem key={task.id} task={task} />;
      })}
    // 〜省略〜
  );
};

TaskItem.tsx(子コンポーネント)
export function TaskItem({ task }: { task: Task }) {
  const handleComplete = async () => {
    await fetch(`http://localhost:3000/tasks/${task.id}`, {
      method: "PATCH",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ completed: !task.completed }),
    });
  };

  return (
    // 〜省略〜
      <button onClick={handleComplete}>
        ボタン
      </button>
    // 〜省略〜
  );
};

原因

以下の流れで親コンポーネントが再レンダリングされていたようです。

  1. PATCH処理でdb.jsonが更新される
  2. Viteがdb.jsonの変更を検知する
  3. HMRが発動してモジュールが再読み込みされる
  4. 再読み込みによりfetchTasksPromiseが再作成される
  5. データが更新されているためTaskListが再レンダリングされる

解決方法

ズバリdb.jsonを監視対象から除外すればOKです。

vite.config.js
export default {
  // 〜既存の設定〜
  server: {
    watch: {
      ignored: [
        '**/db.json', // json-serverのDBファイルを除外
      ]
    }
  }
}

まとめ

HMRって自分でファイルを編集したとき以外にも発動するんだ〜って勉強になりました。(あたりまえか…)

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?