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;

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


当前回答

我使用CodeSandbox和删除防止了这个问题。

CodeSandbox_sample

其他回答

我遇到过这样的问题:

const [onChainNFTs, setOnChainNFTs] = useState([]);

将触发useEffect两次:

useEffect(() => {
    console.log('do something as initial state of onChainNFTs changed'); // triggered 2 times
}, [onChainNFTs]);

我确认组件MOUNTED ONLY ONCE和setOnChainNFTs没有被调用不止一次-所以这不是问题所在。

我通过将onChainNFTs的初始状态转换为null并进行空检查来修复它。

e.g.

const [onChainNFTs, setOnChainNFTs] = useState(null);
useEffect(() => {
if (onChainNFTs !== null) {
    console.log('do something as initial state of onChainNFTs changed'); // triggered 1 time!
}
}, [onChainNFTs]);

我使用CodeSandbox和删除防止了这个问题。

CodeSandbox_sample

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

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

this

root.render(
    <App />
);

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

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

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

reactStrictMode: false,

请检查你的index.js

  <React.StrictMode>
    <App />
  </React.StrictMode>

删除<React。StrictMode >包装 您现在应该发射一次

root.render(
    <App />
);