0

Does anyone know why this fetch continues to fire. I have also tried putting it inside a useEffect with no luck. It should only fire once to return once imdbID has loaded.

const WatchOnList = ({ imdbId }) => {
  const [locations, setLocations] = useState([])
  var headers = new Headers();
  headers.append("x-api-key", "API_KEY")

  var requestOptions = {
    method: 'GET',
    headers: headers,
    crossDomain: true,
    redirect: 'follow'
  };

  async function fetchData() {
    const res = await fetch(`${awsApiUrl}?imdb_id=${imdbId}`, requestOptions);
    res
      .json()
      .then((res) => {
        setLocations(res)
        console.log(locations)
      })
      .catch(error => console.log('error', error));
  }
  fetchData();
2
  • 1
    Every time you call fetchData, it updates the locations useState-hook, which causes a re-render (the function is ran again), which calls fetchData, which causes a re-render, which calls fetchData, which causes a re-render, which calls fetchData.... Commented Oct 8, 2020 at 12:27
  • 3
    Put it inside a useEffect hook and put imdbId into the dependency array. Everything between var headers and fetchData(). Commented Oct 8, 2020 at 12:27

1 Answer 1

3

With the current structure, the request will fire on every re-render. Which will be quite often in a React app. useEffect is the right place for such a function. But there are some caveats:

  1. You can't make useEffect async, you have to create an async function inside the hook instead and call it afterward.
  2. useEffect will per default run on every update, so you have to tell it explicitly to only run once (like componentDidMount for class components). This can be done by passing an empty array as the second parameter. The hook watches parameters specified in this array and only updates when one of them changes. As it is empty, it only fires once on initialization.

This should work:

 useEffect(() => {
    async function fetchData() {
      const res = await fetch(`${awsApiUrl}?imdb_id=${imdbId}`, requestOptions);
      res
        .json()
        .then(res => {
          setLocations(res);
          console.log(locations);
        })
        .catch(error => console.log("error", error));
    }
    fetchData();
  }, []);

Read more about the behavior of hooks here and here.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.