在使用 useQuery 挂钩后,我在使用自定义挂钩时遇到问题。
目录.jsx
import { Box, Spinner } from "@chakra-ui/react";
import ProductPage from "../../components/Products/ProductPage";
import useBeers from "../../hooks/useBeers";
import useProductData from "../../hooks/useProductData";
const Catalogue = () => {
const { data: products, isLoading } = useBeers();
const productData = useProductData(products);
if (isLoading) return <Spinner />;
return (
<Box>
<ProductPage productData={productData} />
</Box>
);
};
export default Catalogue;
所以,我希望我的 useProductData 仅当已经从 useBeers 获取产品时才执行。 使用Beers.js
import { useQuery } from "@tanstack/react-query";
import axios from "axios";
const useBeers = () =>
useQuery({
queryKey: ["beer"],
queryFn: () =>
axios.get("localhost:3001/api/beers").then((response) => response.data),
});
export default useBeers;
使用ProductData.js
import { useState } from "react";
function useProductData(products) {
const brands = products.map(({ id, brand }) => ({
id,
brand,
}));
const prices = products.map((item) => item.price);
const min = Math.min(...prices);
const max = Math.max(...prices);
const title = "Crowlers"; // TODO
const uniqueBrands = brands.filter(
(item, index, self) =>
index === self.findIndex((t) => t.brand === item.brand)
);
const [filteredValues, setFilteredValues] = useState([min, max]);
const [checkedBrands, setCheckedBrands] = useState({});
const brandFilterData = { uniqueBrands, checkedBrands, setCheckedBrands };
const priceFilterData = { min, max, filteredValues, setFilteredValues };
const isVoucher = products.every((product) =>
product.name.includes("Voucher")
);
return {
filteredValues,
checkedBrands,
products,
title,
brandFilterData,
priceFilterData,
isVoucher,
};
}
export default useProductData;
我尝试仅在 !isLoading 像这样的情况下更改执行 useProductData 的行顺序,但它没有按我的预期工作,我遇到了错误: React Hook“useProductData”被有条件地调用。 React Hooks 必须在每个组件渲染中以完全相同的顺序调用。您是否在提前返回后不小心调用了 React Hook?
const { data: products, isLoading } = useBeers();
if (isLoading) return <Spinner />;
const productData = useProductData(products);
要解决此问题,请确保无条件调用您的钩子,这意味着它们以相同的顺序并在功能组件的顶层调用。 尝试这样:
import { Box, Spinner } from "@chakra-ui/react";
import ProductPage from "../../components/Products/ProductPage";
import useBeers from "../../hooks/useBeers";
import useProductData from "../../hooks/useProductData";
const Catalogue = () => {
const { data: products, isLoading } = useBeers();
if (isLoading) return <Spinner />;
// Move useProductData inside the component body
const productData = useProductData(products);
return (
<Box>
{products && <ProductPage productData={productData} />}
</Box>
);
};
export default Catalogue;