{const[count,setCount]=useS"> Wie kann man effektiv damit umgehen, dass useEffect in React zweimal ausgeführt wird?-Fragen und Antworten zum chinesischen PHP-Netzwerk
Wie kann man effektiv damit umgehen, dass useEffect in React zweimal ausgeführt wird?
P粉759457420
P粉759457420 2023-10-20 00:00:23
0
2
664

Ich habe einen Zähler unduseEffect中的console.log()来记录我的状态中的每个更改,但是useEffectwird beim Montieren zweimal aufgerufen. Ich verwende React 18. Hier ist die CodeSandbox für mein Projekt und der Code unten:

import { useState, useEffect } from "react"; const Counter = () => { const [count, setCount] = useState(5); useEffect(() => { console.log("rendered", count); }, [count]); return ( 

Counter

{count}
); }; export default Counter;

P粉759457420
P粉759457420

Antworte allen (2)
P粉156532706

更新:回顾一下这篇文章,稍微明智一点,请不要这样做。

使用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); }; }
    P粉459440991

    自 React 18 起,当您使用StrictMode进行开发时,

    useEffect在挂载时被调用两次是正常的。以下是他们在文档

    这看起来很奇怪,但最终,我们通过缓存 HTTP 请求并在有两个调用时使用清理函数来编写更好的 React 代码,无错误,符合当前指南,并与未来版本兼容一个问题。这是一个例子:

    /* 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;

    在这篇非常详细的文章中,React 团队解释了useEffect前所未有并举例说明:

    对于您的特定用例,您可以保持原样,无需担心。并且您不应该尝试将这些技术与useEffect中的useRefif语句一起使用以使其触发一次,或删除StrictMode,因为正如您可以在文档

    /* 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`); // ...

    如果您仍然遇到问题,也许您正在使用useEffect,正如他们在不是效果:初始化应用程序不是效果:购买产品,我建议您阅读文章作为一个整体。

      Neueste Downloads
      Mehr>
      Web-Effekte
      Quellcode der Website
      Website-Materialien
      Frontend-Vorlage
      Über uns Haftungsausschluss Sitemap
      Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!