Persoalannya
Semasa mengerjakan projek React, saya menghadapi masalah dengan cangkuk useEffect. Matlamat saya adalah untuk mengambil data daripada API sekali sahaja apabila komponen itu dipasang. Walau bagaimanapun, useEffect terus berjalan beberapa kali, walaupun saya menyediakan tatasusunan kebergantungan kosong.
Berikut ialah coretan kod:
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;
Walaupun tatasusunan kebergantungan kosong ([]), useEffect telah dilaksanakan beberapa kali. Saya cuba memulakan semula pelayan pembangunan, tetapi isu itu berterusan. Selepas beberapa penyelidikan dan penyelesaian masalah, saya mengenal pasti punca dan menyelesaikannya.
Jawapannya
Mengapa Ini Berlaku
Mod Tegas dalam Pembangunan:
Jika apl anda berjalan dalam mod pembangunan React dengan StrictMode didayakan, React sengaja melekap dan menyahlekap komponen beberapa kali. Ini ialah tingkah laku pembangunan sahaja yang bertujuan untuk mengesan kesan sampingan yang boleh menyebabkan isu.
Paparan semula atau Penggantian Modul Panas (HMR):
Semasa pembangunan, perubahan dalam kod mungkin mencetuskan Penggantian Modul Panas, menyebabkan komponen itu dipaparkan semula dan useEffect untuk dilaksanakan semula.
Cara Membetulkan atau Mengendalikan Tingkah Laku Ini
Kenal pasti Mod Ketat:
Jika anda menggunakan StrictMode, fahami bahawa tingkah laku ini hanya berlaku dalam pembangunan dan tidak akan menjejaskan binaan pengeluaran. Anda boleh melumpuhkannya buat sementara waktu dengan mengalih keluar
import React from "react"; import ReactDOM from "react-dom"; import App from "./App"; ReactDOM.render(<App />, document.getElementById("root"));
Walau bagaimanapun, adalah lebih baik untuk membiarkannya didayakan dan menyesuaikan kod anda untuk mengendalikan kemungkinan kesan sampingan dengan anggun.
Halang Panggilan API Pendua:
Gunakan bendera untuk memastikan panggilan API berlaku sekali sahaja semasa kitaran hayat komponen, malah
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;
Menggunakan useRef memastikan bahawa panggilan API berlaku sekali sahaja, tanpa mengira pemaparan tambahan yang disebabkan oleh StrictMode.
Pengambilan Utama
. Mod Ketat React dalam pembangunan adalah disengajakan dan selamat untuk ditinggalkan.
. Binaan pengeluaran tidak akan menghadapi masalah ini. . Gunakan useRef atau teknik lain untuk menguruskan kesan sampingan apabila perlu.
Gunakan useRef atau teknik lain untuk menguruskan kesan sampingan apabila perlu.
Binaan pengeluaran tidak akan menghadapi isu ini.
Gunakan useRef atau teknik lain untuk menguruskan kesan sampingan apabila perlu.
Atas ialah kandungan terperinci Mengapakah cangkuk React useEffect saya berjalan beberapa kali walaupun dengan tatasusunan pergantungan kosong?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!