React Hooks:即使使用空数组作为参数,也会调用两次 useEffect()

新手上路,请多包涵

我是 reactJS 的新手并且正在编写代码,以便在从 DB 加载数据之前,它会显示加载消息,然后在加载之后,使用加载的数据渲染组件。为此,我同时使用了 useState 钩子和 useEffect 钩子。这是代码:

问题是,当我检查 console.log 时,useEffect 被触发了两次。因此,代码会两次查询相同的数据,应该避免这种情况。

下面是我写的代码:

 import React from 'react';
import './App.css';
import {useState,useEffect} from 'react';
import Postspreview from '../components/Postspreview'

const indexarray=[]; //The array to which the fetched data will be pushed

function Home() {
   const [isLoading,setLoad]=useState(true);
   useEffect(()=>{
      /*
      Query logic to query from DB and push to indexarray
      */
          setLoad(false);  // To indicate that the loading is complete
    })
   },[]);
   if (isLoading===true){
       console.log("Loading");
       return <div>This is loading...</div>
   }
   else {
       console.log("Loaded!"); //This is actually logged twice.
       return (
          <div>
             <div className="posts_preview_columns">
             {indexarray.map(indexarray=>
             <Postspreview
                username={indexarray.username}
                idThumbnail={indexarray.profile_thumbnail}
                nickname={indexarray.nickname}
                postThumbnail={indexarray.photolink}
             />
             )}
            </div>
         </div>
         );
    }
}

export default Home;

有人可以帮助我理解为什么它被调用两次,以及如何正确修复代码吗?非常感谢!

原文由 J.Ko 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.3k
2 个回答

将 console.log 放在 useEffect 中

可能您还有其他副作用导致组件重新呈现,但 useEffect 本身只会被调用一次。您可以使用以下代码肯定地看到这一点。

 useEffect(()=>{
      /*
      Query logic
      */
      console.log('i fire once');
},[]);

如果日志“我触发一次”被多次触发,则意味着您的问题是三件事之一。

此组件在您的页面中出现多次

这应该很明显,您的组件在页面中出现了几次,每个都将安装并运行 useEffect

树上更高的东西正在卸载和重新安装

该组件被强制卸载并在其初始渲染时重新安装。这可能类似于在树的更高处发生的“关键”变化。您需要使用此 useEffect 升级每个级别,直到它只渲染一次。那么您应该能够找到原因或重新安装。

React.Strict 模式开启

StrictMode 渲染组件两次(在开发而不是生产上),以检测代码的任何问题并警告您(这可能非常有用)。

这个答案由@johnhendirx 指出并由@rangfu 编写,如果这是您的问题,请查看 链接 并给他一些爱。如果您因此遇到问题,通常意味着您没有将 useEffect 用于其预期目的。在 beta 文档中有一些关于此的重要信息,您可以 在此处 阅读

原文由 Joe Lloyd 发布,翻译遵循 CC BY-SA 4.0 许可协议

从 index.js 中删除 这段代码将是

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

这个

root.render(
    <App />
);

React StrictMode 在开发服务器上渲染组件两次

原文由 Md Yeasin Arafat 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进