但是我什么时候去取 获取网址已过时,仅在下一次渲染时正确。
console.log('获取网址:', url.href);
在浏览器中显示如下:
新网址:https://api-storage-products.vercel.app/products?_page=2&_limit=12
获取网址:https://api-storage-products.vercel.app/products?_page=1&_limit=12
也就是说,它没有执行我想要的 url 的获取。
当我使用正常的获取时,它可以工作,但我无法缓存它,因为网址多次更改,它最终会生成将通过缓存解决的请求累积,这就是我使用react-query的原因,但是我在更新 fetchData 中的 url 时遇到问题。
这是我的代码:
import React, { useState, useEffect } from 'react';
import { useQuery } from '@tanstack/react-query';
import { SearchParams } from '@/types/SearchParams';
import { useSearchParams } from 'next/navigation';
export default function useQueryProducts(params: SearchParams) {
const searchParams = useSearchParams();
const _page = searchParams.get('_page') || '1';
const typeProduct = searchParams.get('typeProduct');
const _sort = searchParams.get('_sort');
const search_query = searchParams.get('search_query');
const perPage = 12;
const queryProduct = search_query?.replace(/\s+(?=\S)/g, '%20');
const [quantity, setQuantity] = useState<null | number>(null);
React.useEffect(() => {
const fetchQuantity = async () => {
let urlQuantity = 'https://api-storage-products.vercel.app/quantitys';
if (search_query) {
urlQuantity = `https://api-storage-products.vercel.app/products?q=${search_query.replace(
/\s+(?=\S)/g,
'%20',
)}`;
}
try {
const response = await fetch(urlQuantity);
if (!response.ok) {
throw new Error(`Erro ao buscar produtos: ${response.statusText}`);
}
const quantityData = await response.json();
if (!search_query) {
if (!typeProduct) {
setQuantity(Number(quantityData.allProducts));
}
if (typeProduct === 'allProducts') {
setQuantity(Number(quantityData.allProducts));
}
if (typeProduct === 'mensClothing') {
setQuantity(Number(quantityData.mensClothing));
}
if (typeProduct === 'womansClothing') {
setQuantity(Number(quantityData.womansClothing));
}
} else {
setQuantity(quantityData.length);
}
} catch (error) {
setQuantity(null);
}
};
fetchQuantity();
}, [search_query, typeProduct]);
const baseUrl = 'https://api-storage-products.vercel.app/products';
const [url, setUrl] = useState(
new URL(`${baseUrl}?_page=${_page}&_limit=12`),
);
const fetchData = async () => {
const response = await fetch(url.href);
if (!response.ok) {
throw new Error(`Erro ao buscar produtos: ${response.statusText}`);
}
console.log('url do fetch:', url.href);
return response.json();
};
useEffect(() => {
const newUrl = new URL(
`https://api-storage-products.vercel.app/products?_page=${_page}&_limit=12`,
);
if (typeProduct && typeProduct !== 'allProducts') {
newUrl.searchParams.append('category', typeProduct);
}
if (_sort) {
let sortField = '';
let order = '';
if (_sort === 'news') {
sortField = 'id';
order = 'desc';
} else if (_sort === 'LowerHigher') {
sortField = 'price';
order = 'asc';
} else if (_sort === 'HigherLower') {
sortField = 'price';
order = 'desc';
}
if (sortField && order) {
newUrl.searchParams.append('_sort', sortField);
newUrl.searchParams.append('_order', order);
}
}
if (queryProduct) {
newUrl.searchParams.append('q', queryProduct);
}
console.log('newUrl:', newUrl.href);
setUrl(newUrl);
}, [_page, perPage, typeProduct, _sort, queryProduct]);
const { isLoading, data, isError, refetch } = useQuery({
queryKey: ['products', _page, perPage, queryProduct, _sort, typeProduct],
queryFn: fetchData,
staleTime: 1000 * 60 * 60 * 24,
});
return { isLoading, data, isError, refetch, quantity, perPage };
}