Rumah  >  Soal Jawab  >  teks badan

Bagaimana cara berkesan menangani useEffect berjalan dua kali dalam React?

Saya mempunyai kaunter dan useEffect 中的 console.log() 来记录我的状态中的每个更改,但是 useEffect dipanggil dua kali apabila dipasang. Saya menggunakan React 18. Berikut ialah CodeSandbox untuk projek saya dan kod di bawah:

import  { useState, useEffect } from "react";

const Counter = () => {
  const [count, setCount] = useState(5);

  useEffect(() => {
    console.log("rendered", count);
  }, [count]);

  return (
    <div>
      <h1> Counter </h1>
      <div> {count} </div>
      <button onClick={() => setCount(count + 1)}> click to increase </button>
    </div>
  );
};

export default Counter;

P粉759457420P粉759457420337 hari yang lalu717

membalas semua(2)saya akan balas

  • P粉156532706

    P粉1565327062023-10-20 11:55:03

    KEMASKINI: Lihat kembali siaran ini dan jadilah lebih bijak dan tolong jangan lakukan ini.

    Gunakan ref或创建一个没有的自定义hook.

    export const useClassicEffect = createClassicEffectHook();
    
    function createClassicEffectHook() {
      if (import.meta.env.PROD) return React.useEffect;
    
      return (effect: React.EffectCallback, deps?: React.DependencyList) => {
        React.useEffect(() => {
          let isMounted = true;
          let unmount: void | (() => void);
    
          queueMicrotask(() => {
            if (isMounted) unmount = effect();
          });
    
          return () => {
            isMounted = false;
            unmount?.();
          };
        }, deps);
      };
    }

    balas
    0
  • P粉459440991

    P粉4594409912023-10-20 09:39:10

    Sejak React 18, apabila anda menggunakan StrictMode 进行开发时,

    useEffect adalah perkara biasa untuk dipanggil dua kali semasa pemasangan. Inilah yang mereka ada dalam Dokumentasi:

    Ini mungkin kelihatan pelik, tetapi pada akhirnya, kami menulis kod React yang lebih baik dengan menyimpan cache permintaan HTTP dan menggunakan fungsi pembersihan apabila terdapat isu antara dua panggilan, bebas pepijat, mematuhi garis panduan semasa dan serasi dengan versi masa hadapan . Berikut adalah contoh:

    /* Having a setInterval inside an useEffect: */
    
    import { useEffect, useState } from "react";
    
    const Counter = () => {
      const [count, setCount] = useState(0);
    
      useEffect(() => {
        const id = setInterval(() => setCount((count) => count + 1), 1000);
    
        /* 
           Make sure I clear the interval when the component is unmounted,
           otherwise, I get weird behavior with StrictMode, 
           helps prevent memory leak issues.
        */
        return () => clearInterval(id);
      }, []);
    
      return 
    {count}
    ; }; export default Counter;

    Dalam artikel yang sangat terperinci ini, pasukan React menerangkan useEffect seperti tidak pernah berlaku sebelum ini dan menggambarkannya dengan contoh:

    Untuk kes penggunaan khusus anda, anda boleh membiarkannya seperti sedia ada, jangan risau. Dan anda tidak boleh cuba menggunakan teknik ini dengan useEffect 中的 useRefif 语句一起使用以使其触发一次,或删除 StrictMode useRef dan if pernyataan dalam useEffect untuk membuatnya menyala sekali, atau mengalih keluar

    StrictMode kerana seperti yang Anda dapati ia di

    DokumenuseEffect ,正如他们在 /* As a second example, an API call inside an useEffect with fetch: */ useEffect(() => { const abortController = new AbortController(); const fetchUser = async () => { try { const res = await fetch("/api/user/", { signal: abortController.signal, }); const data = await res.json(); } catch (error) { // ℹ️: The error name is "CanceledError" for Axios. if (error.name !== "AbortError") { /* Logic for non-aborted error handling goes here. */ } } }; fetchUser(); /* Abort the request as it isn't needed anymore, the component being unmounted. It helps avoid, among other things, the well-known "can't perform a React state update on an unmounted component" warning. */ return () => abortController.abort(); }, []);

    function TodoList() {
      const todos = useSomeDataFetchingLibraryWithCache(`/api/user/${userId}/todos`);
      // ...
    Jika anda masih menghadapi masalah, mungkin anda menggunakan useEffect dan seperti yang mereka katakan pada useEffect di tempat pertama > /belajar/menyegerakkan-dengan-kesan#not-an-effect-initializing-the-application" rel="noreferrer">Bukan Kesan: Memulakan Aplikasi dan

    Bukan Kesan: Membeli Produk 🎜 , saya syorkan anda membaca artikel 🎜 🎜Secara keseluruhan. 🎜

    balas
    0
  • Batalbalas