【Tauri】App.tsxが2回実行される問題について【React/useEffect/Strict Mode】

javascript-article

Reactの場合、useEffectはデバッグ時に二度走る

要素の検証のコンソールに同じ文字列が二行ずつ表示されていて、「なんじゃこりゃ!?」と思った方もいらっしゃるでしょう。

これはバグではなく仕様(Strict Mode)であり、React 18.0.x, 18.1.x, 18.2.x〜で起こることだそうです。

対応方法についての議論は下記リンクにありました。

Bug: useEffect runs twice on component mount (StrictMode, NODE_ENV=development)

2回実行される問題についての対処方法

今回私は、Rust言語を用いたGUIフレームワーク「Tauri」で実際の挙動に出会いましたので、Tauriで同じように躓いている方が解決できるよう記しておきます。

ちなみに使用した雛形はtauri-apps / create-tauri-app v3.4.0 です。

変更を加えるファイルのパスは「/プロジェクト名/src/main.tsx」になります。

変更前

import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import "./styles.css";

ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
    <react.strictmode>
    <app></app>
    </react.strictmode>
);

変更後

import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import "./styles.css";

ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
  // <react.strictmode>
    <app></app>
  // </react.strictmode>
);

再度要素の検証のコンソールで確認してみてください。きっとうまく対応できているはずです。

React公式によると、

将来的には、React が状態を維持しながら UI のセクションを追加および削除できるようにする機能を追加したいと考えています。たとえば、ユーザーがタブで画面から離れて戻ると、React はすぐに前の画面を表示できる必要があります。これを行うために、React は、アンマウントする前に使用されたのと同じコンポーネント状態を使用して、ツリーの再マウントをサポートします。

この機能により、すぐに使用できる React のパフォーマンスが向上しますが、コンポーネントは、複数回マウントおよび破棄されるエフェクトに対して回復力がある必要があります。ほとんどのエフェクトは何も変更しなくても機能しますが、一部のエフェクトは、destroy コールバックでサブスクリプションを適切にクリーンアップしないか、マウントまたは破棄が 1 回だけであると暗黙的に想定します。

これらの問題を表面化させるために、React 18 では Strict Mode に開発専用の新しいチェックが導入されています。この新しいチェックは、コンポーネントが初めてマウントされるたびに、すべてのコンポーネントを自動的にアンマウントして再マウントし、2 回目のマウントで以前の状態を復元します。

また、これらは開発時にのみ適用されるので、特に本番公開時には問題ないことも触れられています。

About Naoki 24 Articles
デザインを含めたフロントエンドから、インフラ含めたバックエンドまで広く浅く活動しているエンジニアです。主にSaasの開発・営業・運営管理などをしております。毎日デスマーチがモットーなブラックエンジニアです。 私が管理しているクラウドソフトウェアがこちらです→まとめツール倶楽部『MTCsystem』

Be the first to comment

Leave a Reply

Your email address will not be published.


*


CAPTCHA


日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)