嗨大家!昨天跟大家分享一個 library 叫做 SWR,文章在這裡~ 今天用 SWR 新增了小功能,使用者可以輸入 Github username 然後列出該 user 的所有 public repository,可以在這裡試試看喔。
fetcher
Function像這篇文章提到的,使用 useSWR
時,我們要提供一個 fetcher
function 去抓取資料。這 function 要回傳 data,發生錯誤時回 error:
const fetcher = (user, page) =>
// Github API:列出該 user 的公開 repositories
// user:Github username
// page:做 pagination (分頁) 用的
fetch(`https://api.github.com/users/${user}/repos?page=${page}`)
.then((res) => res.json())
.then((data) => {
// API 找不到 user 時會回傳 { message: "Not Found" }
// 所以在這裡判斷 data 是否包含 message
if ("message" in data) {
throw new Error(data.message);
}
// 全部正常的話,把 data 回傳給 SWR 處理
return data;
});
因為我們發 API 請求時需要給 user
和 page
這兩個 parameters,所以我們的 component 也要存這兩個參數當 state:
const [input, setInput] = useState(""); // input 用的
const [user, setUser] = useState(input); // Github username
const [page, setPage] = useState(1); // 當頁
在這裡把 input
和 user
拆開是因為不想要使用者每打字的同時發送請求,而是使用者按按鈕時,才會 setUser(input)
。
const handleClick = () => {
setUser(input);
setPage(1); // 換 user 代表也要從第一頁開始看
};
useSWR
有了 fetcher
function 和需要的參數,我們可以開始寫 SWR hook 了!不過我們只想要使用者有輸入 user
的時候才會發送請求,其他時間不要做任何事,而且昨天我們看了 useSWR
只用 string 當 key
,那我們今天同時有 user
和 page
,怎麼辦?
const { data: repos, error } = useSWR(user ? [user, page] : null, fetcher);
key
,array 裡面也可以放 object (物件),不過要注意,SWR 只做 shallow compare,代表 const a = {}; const b = {};
而 a
不等於 b
key
依賴其他的參數使得 key
有可能是 falsy 的時候,SWR 不會發任何請求。所以 user ? [user, page] : null
,代表沒有 user
的時候我們不會去呼叫 Github API 喔~現在可以開始顯示資料了!
// error 時顯示 error message
{error
? "User not found"
// 把每個 repo 用 RepoCard 去顯示~
: repos?.map((repo) => <RepoCard key={repo.id} data={repo} />)}
我們會看到以下的畫面~
今天的文章很短,如果有什麼不清楚的歡迎問我喔!使用了 SWR,資料會自動被 cache,只有第一次抓取的時候會需要時間,第二次之後,資料會直接出現,完全不用等的意思XD
大家可以試試看(這裡~),換頁或重整畫面都不用等!
祝大家週末愉快!
晚安 <3