41 lines
1.3 KiB
JavaScript
41 lines
1.3 KiB
JavaScript
import { useState, useEffect, useCallback } from "react";
|
||
import { useSearchPosts } from "./useSearchPosts";
|
||
|
||
/**
|
||
* Поиск объявлений по нескольким выбранным городам, с объединением
|
||
* результатов без дублей. Автоматически перезапускается при смене
|
||
* selectedCities.
|
||
*/
|
||
export function useCityFeed(selectedCities) {
|
||
const { loading: cityLoading, searchPosts } = useSearchPosts();
|
||
const [cityAds, setCityAds] = useState([]);
|
||
|
||
const searchCities = useCallback((citiesToSearch) => {
|
||
if (!citiesToSearch.length) return Promise.resolve([]);
|
||
return Promise.all(citiesToSearch.map(c => searchPosts(c))).then(results => {
|
||
const seen = new Set();
|
||
const merged = [];
|
||
results.flat().forEach(ad => {
|
||
if (!seen.has(ad.id)) {
|
||
seen.add(ad.id);
|
||
merged.push(ad);
|
||
}
|
||
});
|
||
return merged;
|
||
});
|
||
}, [searchPosts]);
|
||
|
||
useEffect(() => {
|
||
if (selectedCities.length === 0) {
|
||
setCityAds([]);
|
||
return;
|
||
}
|
||
let cancelled = false;
|
||
searchCities(selectedCities).then(result => {
|
||
if (!cancelled) setCityAds(result);
|
||
});
|
||
return () => { cancelled = true; };
|
||
}, [selectedCities, searchCities]);
|
||
|
||
return { cityAds, cityLoading, searchCities };
|
||
} |