React error: warning maximum update depth exceeded

Viewed 630

I have added a screen from where admin can add products to store. Whenever I try to enter this page I get following warning and it keeps on repeating until my browser freezes or crashes:

Maximum update depth exceeded. This can happen when a component calls setState inside useEffect, but useEffect either doesn't have a dependency array, or one of the dependencies changes on every render. enter image description here

Here is the code for my ProductEditScreen.js

import React, { useState, useEffect } from "react";
import { useDispatch, useSelector } from "react-redux";
import ErrorMessage from "../../components/ErrorMessage/ErrorMessage";
import Loader from "../../components/Loader/Loader";
import { Link } from "react-router-dom";
import { listProductDetails } from "../../redux/actions/productActions";
import "./ProductEditScreen.scss";

const ProductEditScreen = ({ match, history }) => {
  const productID = match.params.id;
  const [name, setName] = useState("");
  const [price, setPrice] = useState(0);
  const [image, setImage] = useState("");
  const [brand, setBrand] = useState("");
  const [category, setCategory] = useState("");
  const [countInStock, setCountInStock] = useState(0);
  const [description, setDescription] = useState("");

  const dispatch = useDispatch();

  const productDetails = useSelector((state) => state.productDetails);
  const { loading, error, product } = productDetails;

  useEffect(() => {
    if (!product.name || product._id !== productID) {
      dispatch(listProductDetails(productID));
    } else {
      setName(product.name);
      setPrice(product.price);
      setImage(product.Image);
      setBrand(product.brand);
      setCategory(product.category);
      setCountInStock(product.setCountInStock);
      setDescription(product.description);
    }
  }, [dispatch, history, product, productID]);

  const submitHandler = (e) => {
    e.preventDefault();
  };

  return (
    <>
      <div className="userEdit-container">
        {/* {loadingUpdate && <Loader />}
        {errorUpdate && <ErrorMessage>{errorUpdate}</ErrorMessage>} */}
        <div className="userEdit-form">
          <h1>EDIT PRODUCT</h1>
          {error ? (
            <ErrorMessage>{error}</ErrorMessage>
          ) : (
            <form onSubmit={submitHandler}>
              <div className="userEdit-form-items">
                <input
                  className="userEdit-input"
                  type="name"
                  placeholder="name"
                  value={name}
                  onChange={(e) => setName(e.target.value)}
                />
                <input
                  className="userEdit-input"
                  type="number"
                  placeholder="Price"
                  value={price}
                  onChange={(e) => setPrice(e.target.value)}
                />
                <input
                  className="userEdit-input"
                  type="text"
                  placeholder="Enter image url"
                  value={image}
                  onChange={(e) => setImage(e.target.value)}
                />
                <input
                  className="userEdit-input"
                  type="text"
                  placeholder="Brand Name"
                  value={brand}
                  onChange={(e) => setBrand(e.target.value)}
                />
                <input
                  className="userEdit-input"
                  type="text"
                  placeholder="Category"
                  value={category}
                  onChange={(e) => setCategory(e.target.value)}
                />
                <input
                  className="userEdit-input"
                  type="number"
                  placeholder="Count In Stock"
                  value={countInStock}
                  onChange={(e) => setCountInStock(e.target.value)}
                />
                <input
                  className="userEdit-input"
                  type="text"
                  placeholder="Description"
                  value={description}
                  onChange={(e) => setDescription(e.target.value)}
                />

                <button type="submit" value="submit">
                  UPDATE
                </button>
                <Link to="/admin/productlist">
                  <button>Go Back</button>
                </Link>
              </div>
            </form>
          )}
        </div>
      </div>
    </>
  );
};

export default ProductEditScreen;

warning says useEffect either doesn't have a dependency array but I have passed all the dependencies. Also, I don't see any dependency changing every render.

1 Answers

As Chris G suggested above in comments I first ran useEffect with empty [] and then added what console recommended me.

enter image description here

useEffect(() => {
    if (!product.name || product._id !== productID) {
      dispatch(listProductDetails(productID));
    } else {
      setName(product.name);
      setPrice(product.price);
      setImage(product.Image);
      setBrand(product.brand);
      setCategory(product.category);
      setCountInStock(product.setCountInStock);
      setDescription(product.description);
    }
  }, [
    dispatch,
    productID,
    product.Image,
    product._id,
    product.brand,
    product.name,
    product.price,
    product.category,
    product.setCountInStock,
    product.description,
  ]);
Related