為了方便,我今天找了一段時間,找到一個不用api key的免費Api,並且可以在後面更換postId,我們就可以假設他是像page的東西,他每一個postId會給我5個Comment, 我們可以利用這個做出無限輪動去增加他postId來抓取更多資料
我的習慣是先寫hook,所以我們就先來寫hook吧
首先可以先拿上面api試試看,可以看到他的型別長這樣
接下來我們先來寫一個簡單的抓api function 並且存到state中,這應該不會太困難,記得我們[]要放進PostId,這樣我們增加或改變它的時候才能再次抓api
接下來是比較困難的了,如果不知道intersectionObserve API的,可以回去看之前那篇,裡面有莫力全大神講解的,我這邊就講解怎麼寫比較好
const observer = useRef<IntersectionObserver | null>(null);
這裡我們使用了
useRef
來創建一個ref
,這個ref
將持有我們的 IntersectionObserver
實例。初始值是 null
,表示當前沒有 observer。const intersectioningRef = useCallback(
useCallback
是一個 React Hook,它返回一個 memoized 的 callback。這意味著它不會在每次渲染時重新創建,只有當它的依賴改變時才會重新創建。(node) => {
這是回調函數的主體。當你的 React component 的某個 DOM 元素被掛載或更新時,這個函數將被調用,並接收這個 DOM 元素作為參數
node
。if (loading) return;
如果當前正在
loading
,就退出函數,不要做任何事情。if (observer.current) {
檢查我們的 observer
ref
是否有值。如果有,這表示我們之前已經創建了一個 IntersectionObserver
實例。observer.current.disconnect();
如果有之前的
IntersectionObserver
實例,我們需要先中斷它的觀察。這是為了確保在掛載新的元素或更新元素時,之前的觀察不會影響新的觀察。observer.current = new IntersectionObserver((entries) => {
創建一個新的
IntersectionObserver
實例,並將其賦值給我們的 observer
ref。if (entries[0].isIntersecting) {
當被觀察的元素(
node
)進入或離開 viewport 時,這個回調將被調用。entries
是一個陣列,包含所有被觀察的元素的信息。在這裡,我們只關心第一個元素。setPostId((prev) => prev + 1);
如果被觀察的元素進入了 viewport,則增加
postId
的值,代表我們已經到最底了。if (node) observer.current.observe(node);
如果
node
存在(即不是 null
或 undefined
),則開始使用我們的 IntersectionObserver
來觀察它。完整程式碼:
接下來要寫component了,這裡就比較簡單
我們只要在最後一個元素放進監聽與他底下loading就好,所以用
comments.length - 1 === index
判斷,這就是hook好的地方,讓整個component變得很乾淨,很簡潔,UI與邏輯分開