React UseEffect 被调用两次

12 浏览
0 Comments

React UseEffect 被调用两次

我在FC组件中有以下代码:

我只想在组件挂载时调用Api并记录信息

控制台日志对于空数组被调用了两次,对于设置相同值被调用了两次。

import * as React from"react";
import Header from"../components/Header";
import Search from"../components/Search";
import Categories from"../components/Categories";
import Carousel from"../components/Carousel";
import CarouselItem from"../components/CarouselItem";
import Footer from"../components/Footer";
import "../assets/styles/App.scss";
const App = () => {
  const [videos, setVideos] = React.useState([]);
  React.useEffect(() => {
    fetch("http://localhost:3000/initalState")
      .then((response) => response.json())
      .then((data) => setVideos(data));
  }, []);
  console.log(videos);
  return (
      
); }; export default App;

然而,我得到了以下输出:

enter image description here

在useEffect内调用:

  React.useEffect(() => {
    fetch("http://localhost:3000/initalState")
      .then((response) => response.json())
      .then((data) => {
        setVideos(data);
        console.log(videos);
      });
  }, []);

返回一个空数组。

0
0 Comments

问题原因:

问题的原因是在代码中使用了React.StrictMode,导致App组件的渲染触发了两次事件。

解决方法:

将ReactDOM.render中的React.StrictMode移除即可解决该问题。

最近我意识到在我的代码中,我正在使用StrictMode来渲染App组件,结果导致某些事件被触发了两次:

ReactDOM.render(
  
    
  ,
  document.getElementById("root")
);

现在,我将代码修改为下面这样:

ReactDOM.render(, document.getElementById("root"));

问题解决了!

当然,移除StrictMode应该是最后的选择。如果你想要更详细的解答,你可以访问以下链接:[stackoverflow.com/questions/72238175](https://stackoverflow.com/questions/72238175)。

0
0 Comments

问题原因:

React的useEffect钩子在组件渲染时会自动运行一次,并且在依赖项发生变化时重新运行。在给useEffect设置了依赖项后,如果依赖项发生变化,useEffect会运行两次。

解决方法:

使用useCallback来避免额外的运行。将setTimeout/server调用包装在useCallback中,然后将该函数作为依赖项传递给useEffect。

代码如下:

const App = () => {
  const [myData, setMyData] = React.useState([]);
  const getData = useCallback(() => { 
    setTimeout(() => {
      console.log("Inside setTimeOut");
      setMyData("HEllo");
    }, 2000);
  }, []);
  useEffect(() => {
    getData();
    console.log("Inside UseEffect", myData);
  }, [getData]);
  return (
    
Inside my App {myData}
); } export default App;

输出结果:

Inside UseEffect  [仅打印一次]

补充说明:

在useEffect之外使用console.log会导致更多的渲染周期。因为getData会有新的数据并重新渲染,再次打印日志。通过将useEffect包装在useEffect中并添加依赖项,只有在依赖项改变时才会运行。

如果移除所有myData的依赖项,同时保留其他console.log打印,会发现Inside UseEffect会打印两次。

0