React useState hook 导致无限渲染

时间:2021-05-28 12:18:40

标签: javascript reactjs react-hooks use-effect use-state

我将根据搜索查询列出所有产品。我将列出产品的所有品牌和卖家信息存储在 useState 钩子中。直到这一点它才有效。现在我想将所有类别存储在 useState 钩子中。

<块引用>

listProducts 是列出的结果版本。这些结果可以由用户单独排序或过滤。并且 defaultProducts 不会受到影响。 defaultProducts 是我从数据库中得到的。

  const { query } = useParams();
  const [products, setProducts] = useState([]);
  const [listProducts, setListProducts] = useState([]);
  const [brands, setBrands] = useState([]);
  const [sellers, SetSellers] = useState([]);
  const [Categories, setCategories] = useState([]);
  const [isLoading, setIsLoading] = useState(false);

  useEffect(() => {
    setIsLoading(true);
    
    axios
      .get(`/api/product/search/${query}`)
      .then((res) => res.data)
      .then((data) => {
        setIsLoading(false);
        setProducts(data.products);
        setListProducts(data.products);

        if (data.products.length < 1) {
          setProducts(data.brands);
          setListProducts(data.brands);
        }
      });
  }, [query]);

  useEffect(() => {
    let brandSet = new Set();
    let sellerSet = new Set();
    let categoriesSet = new Set();

    products.forEach((item) => {
      categoriesSet.add(item.category);
      categoriesSet.add(item.subCategory);
      brandSet.add(item.brand);
      sellerSet.add(item.shop.companyName);
    });

    setCategories([...categoriesSet]);
    setBrands([...brandSet]);
    SetSellers([...sellerSet]);
  }, [products]);

我终于渲染了 ProductFilters 组件。

 <ProductFilters
   DefaultProducts={products}
   ListProducts={listProducts}
   Brands={brands}
   Sellers={sellers}
   Categories={Categories}
   setListProducts={setListProducts}
   Brand={brand}
 />

ProductFilters.js

<FilterTypeSection className="mt-3">
        <FilterType>Categories</FilterType>
        <CategoriesSection>
          {Categories.map((categoryItem, index) => {
            return (
              <CategoryItem
                key={index}
                onClick={
                  category === categoryItem
                    ? setCategory("")
                    : setCategory(categoryItem)
                }
                style={
                  categoryItem === category
                    ? { fontWeight: "bold", color: "black" }
                    : { fontWeight: "normal", color: "var(--text-muted)" }
                }
              >
                {categoryItem}
              </CategoryItem>
            );
          })}
        </CategoriesSection>
</FilterTypeSection>

我列出了上述的卖家和品牌数据,它们奏效了。但是当我添加这段代码时,我收到了这个错误:

Unhandled Rejection (Error): Too many re-renders. React limits the number of renders to prevent an infinite loop.
▶ 18 stack frames were collapsed.
(anonymous function)
src/pages/searchResultsPage.js:162
  159 |   sellerSet.add(item.shop.companyName);
  160 | });
  161 | 
> 162 | setCategories([...categoriesSet]);
      | ^  163 | setBrands([...brandSet]);
  164 | SetSellers([...sellerSet]);
  165 | 

即使我为 Categories 属性设置了默认值,例如 Categories=["a","b","c"] 我仍然会遇到同样的错误。

2 个答案:

答案 0 :(得分:3)

问题

在您的 onClick 函数中,您正在执行函数调用 setCategory("") 。但是你需要的只是一个函数签名,可以在用户点击之后调用。

因此将您的 onClick 更改为内联函数。

onClick={() => {
  category === categoryItem
  ? setCategory("")
  : setCategory(categoryItem)
}

答案 1 :(得分:1)

如果不使用箭头函数,setCategory 函数将被一次又一次地调用。您的 ProductFilters 组件应该是这样的:

<FilterTypeSection className="mt-3">
    <FilterType>Categories</FilterType>
    <CategoriesSection>
        {Categories.map((categoryItem, index) => {
            return (
              <CategoryItem
                key={index}
                onClick={
                  () => category === categoryItem
                    ? setCategory("")
                    : setCategory(categoryItem)
                }
                style={
                  categoryItem === category
                    ? { fontWeight: "bold", color: "black" }
                    : { fontWeight: "normal", color: "var(--text-muted)" }
                }
              >
                {categoryItem}
              </CategoryItem>
            );
        })}
    </CategoriesSection>
</FilterTypeSection>
相关问题