miouri
miouri

Reputation: 409

Infinite Loop Fetching

The state restaurants changes from an input form in the front and updates a database in the back. Then the idea is to show the RestaurantList component with the new added restaurant from the input. The idea is not to use the useContext hook. I´ve tried using the useEffect hook to render the list everytime the restaurant state changes, but this makes infinit GET requests in my backend.

const RestaurantsList = (props) => {
  const [restaurants, setRestaurants] = useState("");

  useEffect(async () => {
    try {
      const response = await fetch("http://localhost:3001/api/v1/restaurants");
      const data = await response.json();
      setRestaurants(data);
      console.log(data);
    } catch (err) {
      console.log(err);
    }
  }, [restaurants]);

...

With this code, the front updates OK and shows the new restaurant, but the back keep making get requests. Why is this happening if the restaurants state isnt changing? Any recommendation? How can I avoid this loop?

I've tried one thing that works and is to remove the preventDefault event when I click the add button. In this way, the page reloads and do what I want but i dont know if it is the best practice:

const AddRestaurant = () => {
  const [name, setName] = useState("");
  const [location, setLocation] = useState("");
  const [priceRange, setPriceRange] = useState("");


 const handleSubmit = async function (e) {
    //e.preventDefault();

    try {
      await fetch("http://localhost:3001/api/v1/restaurants", {
        method: "POST",
        made: "cors",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          name,
          location,
          price_range: priceRange,
        }),
      });
    } catch (err) {
      console.log(err);
    }
    setName("");
    setLocation("");
    setPriceRange("");
  };
 return (
    <div className="mb-4">
      <form action="" on>
        <div className="form-row">
          <div className="col">
            <input
              type="text"
              value={name}
              className="form-control"
              placeholder="Name"
              onChange={nameUpdate}
            />
          </div>
          <div className="col">
            <input
              className="form-control"
              value={location}
              type="text"
              placeholder="Location"
              onChange={locationUpdate}
            />
          </div>
          <div className="col">
            <select
              className="custom-select my-1 mr-sm-2"
              value={priceRange}
              onChange={(e) => setPriceRange(e.target.value)}
            >
              <option disabled>Price Range</option>
              <option value="1">$</option>
              <option value="2">$$</option>
              <option value="3">$$$</option>
              <option value="4">$$$$</option>
              <option value="5">$$$$$</option>
            </select>
          </div>
          <button className="btn btn-primary" onClick={handleSubmit}>
            Add
          </button>
        </div>
      </form>
    </div>
  );
};

export default AddRestaurant;

Upvotes: 1

Views: 1805

Answers (1)

Ryan Speciale
Ryan Speciale

Reputation: 178

are you saying that RestaurantsList() is throwing the infinite loop? Everything I see here is frontend code. The reason you are getting an infinite loop is because you have a set dependency of [restaurants] in your useEffect hook. Every time it grabs that data it gets updated, causing it call the function again. If you just want it to fetch the data once then leave the dependency array blank.

Try this:

   const [restaurants, setRestaurants] = useState("");
   
   useEffect(() => {
            const fetchData = async () => {
            const response = await fetch('http://localhost:3001/api/v1/restaurants')
            const data = await response.json();
            console.log(data);
            setRestaurants(data);
        }
        fetchData();
    }, []);```

Upvotes: 2

Related Questions