javascriptreactjsreact-hooks

why my react project always warning:Maximum update depth exceeded at Navigate


**can someone help me why my project run a alots error about this? I don't see any question about my codes. enter image description here

Here is error:

Warning: 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. at Navigate (http://localhost:3000/static/js/bundle.js:161563:5) at div at O (http://localhost:3000/static/js/bundle.js:168705:6) at div at O (http://localhost:3000/static/js/bundle.js:168705:6) at div at O (http://localhost:3000/static/js/bundle.js:168705:6) at Product (http://localhost:3000/static/js/bundle.js:1761:5) at section at O (http://localhost:3000/static/js/bundle.js:168705:6) at Products at div at O (http://localhost:3000/static/js/bundle.js:168705:6) at ProductList at RenderedRoute (http://localhost:3000/static/js/bundle.js:161243:5) at Routes (http://localhost:3000/static/js/bundle.js:161692:5) at Router (http://localhost:3000/static/js/bundle.js:161623:15) at BrowserRouter (http://localhost:3000/static/js/bundle.js:159844:5) at App

here are the relative codes: App.jsx. This one is setting path for the route.

import React from 'react'
import Cart from './pages/Cart'
import Home from './pages/Home'
import Login from './pages/Login'
import Product from './pages/Product'
import ProductList from './pages/ProductList'
import Register from './pages/Register'
import { BrowserRouter as Router, Navigate, Route, Routes } from "react-router-dom";
const App = () => {
  const user = true;
  return (
    <Router>
      <Routes>
        <Route exact path="/"  element={<Home />} />
        <Route exact path="/products/:category" element={<ProductList />} />
        <Route exact path="/product/:id" element={<Product />} />
        <Route exact path="/cart" element={<Cart />} />
        <Route exact path="/register" element={user ? <Navigate to="/" /> : <Register />} />
        <Route exact path="/login" element={user ? <Navigate to="/" /> : <Login />} />
      </Routes>
    </Router>
  )
}
export default App

Product.jsx This one is running product information,it's also a component. **When I run the url:http:localhost:3000/products/women,it should be show the products belongs to the category:women.**But it runs http:localhost:8000/products/productId,it's wrong.

import React from 'react'
import { useEffect, useState } from 'react';
import Product from './Product';
import axios from "axios"
const Products = ({ cate, filters, sort }) => {
  //const Products = () => {
  console.log(cate, filters, sort)
  const [products, setProducts] = useState([]);
  const [filteredProducts, setFilteredProducts] = useState([]);
  useEffect(() => {
    const getProducts = () => {
      const res = axios.get(
        cate ? `http://localhost:8000/api/products?category=${cate}`
          : "http://localhost:8000/api/products")
        .then(
          function (res) {
            setProducts(res.data);
            console.log(res)
          }
        ).catch(
          function (err) {
            console.log(err)
          });
    }
    getProducts();
  }, [cate]);
  useEffect(() => {
    cate && setFilteredProducts(
      products.filter((item) => (
        Object.entries(filters).every(([key, value]) => {
          return item[key].includes(value);
        }
        )
      ))
    )
  }, [products, cate, filters])
  useEffect(() => {
    if ((sort === "newest")) {
      setFilteredProducts((prev) =>
        [...prev].sort((a, b) => a.createdAt.localeCompare(b.createdAt))
      )
    } else if (sort === "asc") {
      setFilteredProducts((prev) =>
        [...prev].sort((a, b) => a.price - b.price)
      )
    } else {
      setFilteredProducts((prev) =>
        [...prev].sort((a, b) => b.price - a.price)
      )
    }
  })
  return (
    <Container >
        {cate
        ? filteredProducts.map((item) => (
          <Product item={item} key={item._id} />))
        : products.slice(0, 8).map((item) => <Product item={item} key={item._id} />)}
    </Container>
  );
};

pages/Product.jsx. This one is running display part. http:localhost:3000/product/productID**

import { useLocation } from 'react-router-dom'
import { useState, useEffect } from 'react';
import { publicRequest } from './requestMethods';
const Product = () => {
   // ε›žε‚³θ·―εΎ‘
    const location = useLocation();
    const id = location.pathname.split("/")[2];
    const [product, setProduct] = useState({});
    useEffect(() => {
        const getProduct = async () => {
            try {
                const res = await publicRequest.get("/product/find/" + id);
                setProduct(res.data);
            }
            catch { }
}
        getProduct();
    }, [id])

Solution

  • You have to include the missing dependencies in the useEffect dependency array if not any, you can have an empty array [] as dependency

    I could see a missing dep here in below effect:

    useEffect(() => {
      if (sort === "newest") {
        setFilteredProducts((prev) =>
          [...prev].sort((a, b) => a.createdAt.localeCompare(b.createdAt))
        );
      } else if (sort === "asc") {
        setFilteredProducts((prev) => [...prev].sort((a, b) => a.price - b.price));
      } else {
        setFilteredProducts((prev) => [...prev].sort((a, b) => b.price - a.price));
      }
    },[sort]); // here `sort` is missing as dependency
    

    Otherwise it runs on every render, which is what exactly the warning is about πŸ˜‡