I am new to reactJS and am writing code so that before the data is loaded from DB, it will show loading message, and then after it is loaded, render components with the loaded data. To do this, I am using both useState hook and useEffect hook. Here is the code:

问题是,当我检查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;

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


当前回答

您很可能是在启用严格模式的开发环境中检查问题。 要验证这种情况,请搜索<React。StrictMode>标签并删除它,或构建用于生产。双重渲染的问题应该消失了。 来自React官方文档

严格模式不能自动为你检测副作用,但它可以通过使它们更具确定性来帮助你发现它们。这是通过有意地双重调用以下函数来实现的: 传递给useState、useMemo或useReducer的函数 […]

严格模式- Reactjs文档

类似的问题在这里,我的React组件渲染两次,因为严格模式

其他回答

新的React文档(目前处于测试阶段)有一个章节精确地描述了这种行为:

如何处理效果发射两次在开发

从文档中可以看出:

通常,答案是实现清理功能。清除函数应该停止或撤消Effect正在做的任何事情。经验法则是,用户不应该能够区分Effect运行一次(如在生产中)和设置→清理→设置序列(如您在开发中看到的)。

所以这个警告应该让你仔细检查你的useEffect,通常意味着你需要实现一个清理函数。

这是我们使用React.StrictMode时ReactJS的特性。StrictMode为它的后代节点激活额外的检查和警告。因为应用程序不应该崩溃的情况下,任何不良的做法在代码。我们可以说StrictMode是一个安全检查,用于两次验证组件以检测错误。

你会得到这个<React。组件根的StricyMode>。

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

如果你想限制组件渲染两次,你可以删除<React。StrictMode>并检查它。但是在糟糕的代码实践中,使用StrictMode来检测运行时错误是必要的。

删除<反应。从index.js的StrictMode> 这段代码将是

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

this

root.render(
    <App />
);

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

这可能不是理想的解决方案。但我用了一个变通办法。

var ranonce = false;
useEffect(() => {
    if (!ranonce) {

        //Run you code

        ranonce = true
    }
}, [])

尽管useEffect运行两次,但重要的代码只运行一次。

如果你正在使用Next js,将reactStrictMode从“true”更改为false:

将此添加到你的next.config.js中

reactStrictMode: false,