問題
在處理 React 專案時,我遇到了 useEffect 掛鉤的問題。我的目標是在元件安裝時僅從 API 取得資料一次。然而,即使我提供了一個空的依賴項數組,useEffect 仍然運行多次。
這是程式碼片段:
import React, { useEffect, useState } from "react"; import axios from "axios"; const MyComponent = () => { const [data, setData] = useState([]); useEffect(() => { console.log("Fetching data..."); axios.get("https://jsonplaceholder.typicode.com/posts") .then(response => setData(response.data)) .catch(error => console.error(error)); }, []); return ( <div> <h1>Data</h1> <ul> {data.map(item => ( <li key={item.id}>{item.name}</li> ))} </ul> </div> ); }; export default MyComponent;
儘管依賴項數組 ([]) 為空,但 useEffect 仍被執行了多次。我嘗試重新啟動開發伺服器,但問題仍然存在。經過一些研究和故障排除後,我確定了根本原因並解決了它。
答案
為什麼會發生這種情況
嚴格的開發模式:
如果您的應用程式在啟用了 StrictMode 的 React 開發模式下運行,React 會故意多次掛載和卸載元件。這是一種僅限於開發的行為,旨在檢測可能導致問題的副作用。
重新渲染或熱模組替換(HMR):
開發過程中,程式碼的變更可能會觸發模組熱替換,導致元件重新渲染,useEffect再次執行。
如何修復或處理此行為
辨識嚴格模式:
如果您使用 StrictMode,請了解此行為僅發生在開發中,不會影響生產建置。您可以透過刪除
來暫時停用它
import React from "react"; import ReactDOM from "react-dom"; import App from "./App"; ReactDOM.render(<App />, document.getElementById("root"));
但是,最好保持其啟用狀態並調整您的程式碼以優雅地處理潛在的副作用。
防止重複的 API 呼叫:
使用標誌來確保 API 呼叫在元件的生命週期內只會發生一次,甚至
import React, { useEffect, useState, useRef } from "react"; import axios from "axios"; const MyComponent = () => { const [data, setData] = useState([]); const isFetched = useRef(false); useEffect(() => { if (isFetched.current) return; console.log("Fetching data..."); axios.get("https://api.example.com/data") .then(response => setData(response.data)) .catch(error => console.error(error)); isFetched.current = true; }, []); return ( <div> <h1>Data</h1> <ul> {data.map(item => ( <li key={item.id}>{item.name}</li> ))} </ul> </div> ); }; export default MyComponent;
使用 useRef 可確保 API 呼叫僅發生一次,而不管 StrictMode 導致的額外渲染如何。
要點
。 React 開發中的嚴格模式是有意為之的,可以安全地保留。
。生產版本不會有這個問題。 。必要時使用 useRef 或其他技術來管理副作用。
必要時使用 useRef 或其他技術來管理副作用。
生產版本不會有這個問題。
必要時使用 useRef 或其他技術來管理副作用。
以上是為什麼我的 React useEffect 鉤子即使在依賴項數組為空的情況下也會運行多次?的詳細內容。更多資訊請關注PHP中文網其他相關文章!