简体   繁体   中英

React UseEffect is being calling twice

I have the following code in FC component:

I just want to call the Api and Log the info when the component is mounted

The console.log is being called twice for empty array and twice for setting the same values.

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 (
    <div className="App">
      <Header></Header>
      <Search></Search>

      <Categories title="Mi Lista">
        <Carousel>
          <CarouselItem />
          <CarouselItem />
          <CarouselItem />
          <CarouselItem />
          <CarouselItem />
        </Carousel>
      </Categories>

      <Categories title="Tendencias">
        <Carousel>
          <CarouselItem />
          <CarouselItem />
        </Carousel>
      </Categories>

      <Categories title="Originales de Platzi Video">
        <Carousel>
          <CarouselItem />
        </Carousel>
      </Categories>

      <Footer />
    </div>
  );
};

export default App;

However, i got the following output:

在此处输入图像描述

Calling within useEffect:

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

returns an empty array.

I just realized i was rendering App in strict Mode, which invokes some events twice:

Strict mode can't automatically detect side effects for you, but it can help you spot them by making them a little more deterministic. This is done by intentionally double-invoking the following functions:

Class component constructor, render, and shouldComponentUpdate methods Class component static getDerivedStateFromProps method Function component bodies State updater functions (the first argument to setState) Functions passed to useState, useMemo, or useReducer

I had this:

ReactDOM.render(

  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById("root")
);

Now

ReactDOM.render(<App />, document.getElementById("root"));

It's solved.

you can use UseCallback to avoid an additional run below is the sample code.

Note: If you directly call setTimeout/server calls inside use effect without wrapping in useCallback , it will be called twice

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 (
    <div className="App">
     Inside my App {myData}
    </div>
  );
}

export default App;

Output:

Inside UseEffect  [printed just once]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM