如何解決 useEffect 運行兩次的問題

React 18 於 2022 年 3 月發佈,改變了 useEffect() 的默認行為。

起初,我甚至沒有意識到這一點,這個改變被埋在了大量的新功能之中。

如果您的應用程式在升級到 React 18 後運作怪異,那是因為 useEffect 的默認行為變成運行兩次

這只在開發模式下發生,但這是每個人構建應用程式的模式。

而且只在嚴格模式下發生,但這是使用 Vite、create-react-app 或 Next.js 構建的應用程式的默認模式。

造成這種情況有其原因。

這並不是您的程式碼有問題,而是 React 現在的運作方式。

唯一的解決辦法是禁用嚴格模式

嚴格模式很重要,因此這只是一個臨時解決辦法,直到您修正了這個改變引入的任何問題。

在 Vite 中,請前往 src/main.jsx,從以下程式碼中刪除 <React.StrictMode> 包裝元件:

import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
import './index.css'

ReactDOM.createRoot(document.getElementById('root')).render(
 <React.StrictMode>
 <App />
 </React.StrictMode>,
)

改為:

import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
import './index.css'

ReactDOM.createRoot(document.getElementById('root')).render(
 <App />
)

在 Next.js 中,您可以在 next.config.js 檔案中添加選項:

reactStrictMode: false

create-react-app 中,您可以在 index.js 檔案中刪除 StrictMode 高階元件,從以下程式碼中刪除:

import React, { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';

import App from './App';

const rootElement = document.getElementById('root');
const root = createRoot(rootElement);

root.render(
 <StrictMode>
 <App />
 </StrictMode>
);

改為:

import React from 'react';
import { createRoot } from 'react-dom/client';

import App from './App';

const rootElement = document.getElementById('root');
const root = createRoot(rootElement);

root.render(
 <App />
);