-2

I have page with few forms components as defined below, everything in front works fine, however if I look my console logs the function Fetchmovies is continuously being executed and throws

caught Error: Too many re-renders. React limits the number of renders to prevent an infinite loop.

Even without error this is undesirable I don't want to make hundreds of calls to the API url. My requirment is just to call the Fetchmovies function once the page loads first time and update Autocomplete component with the returning array. ButI am not sure, why my page is rendered recursively.

import React, { useState } from 'react';

function GetMovies() {
  var [movies_list, setMovies_list] = useState([]);

  async function Fetchmovies() {

    try {
      movies_list = await fetch(url, {
        method: 'GET',
        headers: {
          'Accept': 'application/json',
          'authorization':'token'
        },
      }).then(response => movies_list = response.json());
      console.log(movies_list);
    } catch (e) {
      console.log(e);
    }
  }
  Fetchmovies().then(setMovies_list(movies_list));

  return (
    <Card>
      <Divider />
      <CardContent>
            <Autocomplete
              id='movies'
              name='movies'
              getOptionLabel={(movies_list) => movies_list.service_name}
              multiple
              options={movies_list}
              renderInput={(params) => <TextField {...params} label='Impacted movies:' />}
            />
      </CardContent>
    </Card>
  );

}
export default GetMovies;
Maven
  • 14,587
  • 42
  • 113
  • 174
  • 1
    Just use [useEffect](https://react.dev/reference/react/useEffect) hook to call it only once on launch like `useEffect(() => {Fetchmovies().then(setMovies_list(movies_list));}, [])`, Just spending little effort to search in google you could easily get this answer. – Ravikumar May 18 '23 at 00:56
  • 1
    It rerenders because every time it renders it triggers a new request, which triggers a new render, which ... The solution is the same one you [keep](https://stackoverflow.com/questions/76271306/fetching-json-from-an-url-and-store-it-as-a-list#comment134500383_76271306) being [given](https://stackoverflow.com/questions/76274992/how-to-update-the-list-of-options-of-an-autocomplete-component-after-its-renderi#comment134506565_76274992). – jonrsharpe May 18 '23 at 08:39

2 Answers2

1

You should use useEffect but there are some errors on your fetch and the use of state.

Check here what you can do instead:

import React, { useEffect, useState } from 'react';

function GetMovies() {
  var [movies_list, setMovies_list] = useState([]);

  async function Fetchmovies() {
    try {
      const res = await fetch(url, {
        method: 'GET',
        headers: {
          'Accept': 'application/json',
          'authorization':'token'
        },
      });
      const data = await res.json();
      setMovies_list(data);
    } catch (e) {
      console.log(e);
    }
  }

  useEffect(() => {
    Fetchmovies();
  }, [])

  return (
    <Card>
      <Divider />
      <CardContent>
            <Autocomplete
              id='movies'
              name='movies'
              getOptionLabel={(movies_list) => movies_list.service_name}
              multiple
              options={movies_list}
              renderInput={(params) => <TextField {...params} label='Impacted movies:' />}
            />
      </CardContent>
    </Card>
  );

}
export default GetMovies;
OneQ
  • 1,149
  • 1
  • 8
  • 15
1

This line

Fetchmovies().then(setMovies_list(movies_list));

updates state ... which causes the component to reload .. which calls Fetchmovies again etc.

Wrap your Fetchmovies call un a useEffect hook.

useEffect(() => {
    Fetchmovies().then(setMovies_list(movies_list));
}, [])
Leigh.D
  • 463
  • 5
  • 13