javascript - Is it possible to fetch API without useEffect in React JS? - Stack Overflow

admin2025-04-18  1

Hello i'm newbie here... I found my friend's code when he using useState instead of using useEffect to fetch the API. I tried it and it worked, the code didn't cause an error and infinite loops.

here is for the code

import { useState } from "react";
import { IN_THEATER, POSTER } from "../../../constant/movies";
import { GlobalGet } from "../../../utilities/fetch";

const Service = () => {
  const [movieData, setMovieData] = useState({ data: null, poster: null });

  const fetchMovieData = async () => {
    try {
      let movieRes = await GlobalGet({ url: `${IN_THEATER}` });
      return movieRes;
    } catch (error) {
      console.log(error);
    }
  };

  const fetchPoster = async () => {
    try {
      let posterRes = await GlobalGet({ url: `${POSTER}` });
      return posterRes;
    } catch (error) {
      console.log(error);
    }
  };

  const fetchData = async () => {
    setMovieData({
      data: await fetchMovieData(),
      poster: await fetchPoster(),
    });
  };

  useState(() => { //<=here it is
    fetchData();
  }, []);
  return {
    movieData,
  };
};

export default Service;

And my question is, why it could be happen ? why using useState there doesn't cause an infinite loops ?

Hello i'm newbie here... I found my friend's code when he using useState instead of using useEffect to fetch the API. I tried it and it worked, the code didn't cause an error and infinite loops.

here is for the code

import { useState } from "react";
import { IN_THEATER, POSTER } from "../../../constant/movies";
import { GlobalGet } from "../../../utilities/fetch";

const Service = () => {
  const [movieData, setMovieData] = useState({ data: null, poster: null });

  const fetchMovieData = async () => {
    try {
      let movieRes = await GlobalGet({ url: `${IN_THEATER}` });
      return movieRes;
    } catch (error) {
      console.log(error);
    }
  };

  const fetchPoster = async () => {
    try {
      let posterRes = await GlobalGet({ url: `${POSTER}` });
      return posterRes;
    } catch (error) {
      console.log(error);
    }
  };

  const fetchData = async () => {
    setMovieData({
      data: await fetchMovieData(),
      poster: await fetchPoster(),
    });
  };

  useState(() => { //<=here it is
    fetchData();
  }, []);
  return {
    movieData,
  };
};

export default Service;

And my question is, why it could be happen ? why using useState there doesn't cause an infinite loops ?

Share edited Sep 11, 2022 at 4:43 Fahmi Achmad asked Sep 11, 2022 at 3:27 Fahmi AchmadFahmi Achmad 511 silver badge5 bronze badges 0
Add a ment  | 

2 Answers 2

Reset to default 4

The useState() function can accept an initializer function as its first argument:

const [state, setState] = useState(initializerFunction)

When a function is passed to useState(), that function is only called once before the ponent initially mounts. In your case below, the initializer function is an anonymous arrow function:

useState(() => { // <-- Initializer function invoked once
  fetchData();
}, []);

Here, the initializer function is () => { fetchData(); }, which is invoked once before the initial mount, so the fetchData() method is only called once. The array that is passed as the second argument [] is useless and doesn't do anything in this case as it's ignored by useState(). The above useState would behave the same if you did useState(fetchData);. Because fetchData() is only called once on the initial mount, any state updates of your ponent don't cause the fetchData() function to execute again as it's within the initializer function.

With that said, useState() shouldn't be used for fetching data on mount of your ponent, that's what useEffect() should be used for instead.

Generally it's possible to fetch data from outside of the useEffect hook.

Somewhere in the body of your ponent...

const [fetchedData, setFetchedData] = useState(false)

const someFetchFunc = asyunc (url) => {

setFetchedData(!fetchedData)

const res = await fetch(url)
const data = await res.json()
setMovieData(data)

}

!fetchedData && someFetchFunc()

But this is an antipattern. In this case developer lacks a whole toolset of dealing with possible issues. What if fetching fails?

So, it's generally a good idea to handle all the side effects like fetching in a place that was intended for that. It's useEffect hook)

转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1744951231a276348.html

最新回复(0)