1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
| import { useState, useEffect, useRef, useCallback } from "react"; import { useDispatch } from "react-redux"; import axios from "axios";
const GetDataHooks = (keyword, page, setPage) => { const [newsData, setNewsData] = useState([]); const [loading, setLoading] = useState(false); const [hasMore, setHasMore] = useState(false); const [error, setError] = useState(false);
const API_KEY = process.env.REACT_APP_API_KEY;
const dispatch = useDispatch();
useEffect(() => { setNewsData([]); }, [keyword]);
useEffect(() => { if (keyword && !loading) { const searchTimeout = setTimeout(() => { setLoading(true); setError(false); let cancel; axios({ method: "GET", url: `https://api.nytimes.com/svc/search/v2/articlesearch.json?api-key=${API_KEY}`, params: { q: keyword, sort: "newest", page }, cancelToken: new axios.CancelToken((c) => (cancel = c)), }) .then((res) => { setNewsData((prev) => [...prev, ...res.data.response.docs]); setHasMore(res.data.response.docs.length > 0); setLoading(false); }) .catch((e) => { if (axios.isCancel(e)) return; setError(true); }); dispatch({ type: "SEARCH_HISTORY", payload: keyword }); }, 500); return () => { clearTimeout(searchTimeout); }; } }, [keyword, page]);
const observer = useRef(); const lastCardNewsRef = useCallback( (node) => { console.log("visible"); if (loading) return; if (observer.current) observer.current.disconnect(); observer.current = new IntersectionObserver((entries) => { if (entries[0].isIntersecting && hasMore) { setPage((page) => page + 1); ✅ GetDataHooks(keyword, page, setPage,) } }); if (node) observer.current.observe(node); }, [loading, hasMore] );
return { newsData, loading, lastCardNewsRef }; };
export default GetDataHooks;
|