React功能组件中根据类别过滤数据

问题描述 投票:0回答:1

这是我在 React.js 中的第一个电子商务项目。
我正在显示产品列表,其中我也在左侧显示类别,如下面的屏幕截图所示。

我正在尝试根据类别过滤产品列表。因此,我非常接近实现它,但我面临一个错误(内存泄漏问题)。

错误: 警告:超出最大更新深度。当组件在 useEffect 中调用 setState,但 useEffect 没有依赖项数组,或者依赖项之一在每次渲染时发生更改时,就会发生这种情况。

我哪里出错了? 这是截图:

这是代码:

  const [products, setProducts] = useState([]);
  const [page, setPage] = useState(1);
  const [categories, setCategories] = useState([]);
  const [selectedCategories, setSelectedCategories] = useState([]);


//handling paging
const handlePageChange = (pageNumber) => {
  if (
    pageNumber > 0 &&
    pageNumber <= products.length / 15 &&
    pageNumber !== page
  )
    setPage(pageNumber); 
    
}


const addCategory = (category) => {
  if(!selectedCategories.includes(category)){
      setSelectedCategories(prev => ([...prev, category]))
  }     
}



const removeCategory = (category) => {
  if(selectedCategories.includes(category)){
      const removedList = selectedCategories.filter((item) => (item !== category));
      setSelectedCategories(removedList);
  }
}

const getCategories = () => { 
  fetch('https://dummyjson.com/products/categories')
  .then(res => res.json())  
  .then((data) => {
    setCategories(data);
  })  
  
  .catch((err) => console.log(err));
}

useEffect(() => {
  getCategories() 
  }, [])



const getProducts = () => {
  fetch('https://dummyjson.com/products?limit=90') 
  .then(res => res.json()) 
  .then((data) => {
    if (data.products && data.products.length) setProducts(data.products);
  })  

  .catch((err) => console.log(err));
}



useEffect(() => {
getProducts()
}, [])



useEffect(() => {
  if(selectedCategories.length === 0){
      setProducts(products);

  } else{
    setProducts(products.filter((item)=>(selectedCategories.includes(item.category))));
  }
}, [selectedCategories, products])

这是 JSX 代码: 显示类别。

{categories.map((category) => (
  <div onClick={() => {
    if(selectedCategories.includes(category)){
        removeCategory(category);
    } else{
        addCategory(category);
    }
}}  key={category}> 

      <div className="form-check">
        <input className="form-check-input" type="checkbox" value={category} id={category} />
        <label className="form-check-label" htmlFor={category}>
        {category}     
        </label>
      </div> 
  </div>

))}

显示产品列表。

  {products.length && (
    <div className='row'>
      {products.slice(page * 15- 15, page * 15).map((item)  => (

        <div className='col-lg-4 mb-4 text-center' key={item.id}>
        <div className='product' key={item.id}> 
        <Link to={`/shop/${item.id}/${item.title.replace(/\s+/g, '-').toLowerCase()}`}>
        <div className='list'>
            <div className='p_photo'>
                <img className='img-fluid' src={item.thumbnail} alt={item.title} /> 
            </div>
            
        </div>
        </Link>

        <div className="Stars" style={{"--rating": [item.rating]}} />

        <div className='title mt-2'> <Link to={`/shop/${item.id}/${item.title.replace(/\s+/g, '-').toLowerCase()}`}>{item.title}</Link> </div>
              
        <div className='price mt-2'>    
        <span className='sale'>${item.price}</span> 
        <span className='discount'>({item.discountPercentage}% OFF)</span> 
        </div>
        </div>
        </div>
      
      ))}

    </div>
  )}
reactjs json sorting react-hooks filtering
1个回答
0
投票

问题出现在这里:组件挂载后,它在第一个 useEffect 中调用

getProducts()
。随后,在获取数据后,它会更新
products
状态,触发第二个 useEffect。在第二个 useEffect 中,您已将
[selectedCategories, products]
设置为依赖项数组。

如果

selectedCategories
为空数组,则会进入if语句,调用
setProducts(products)
,再次触发useEffect,产生递归。

const getProducts = () => {
  fetch('https://dummyjson.com/products?limit=90') 
  .then(res => res.json()) 
  .then((data) => {
    if (data.products && data.products.length) setProducts(data.products);
  })  

  .catch((err) => console.log(err));
}



useEffect(() => {
getProducts()
}, [])




useEffect(() => {
  if(selectedCategories.length === 0){
      setProducts(products);

  } else{
    setProducts(products.filter((item)=>(selectedCategories.includes(item.category))));
  }
}, [selectedCategories, products])
© www.soinside.com 2019 - 2024. All rights reserved.