创建 useFetch Hook
export const useFetch = (url) => {
const [status, setStatus] = useState('idle');
const [data, setData] = useState([]);
useEffect(() => {
if (!url) return;
const fetchData = async () => {
setStatus('fetching');
const response = await fetch(url);
const data = await response.json();
setData(data);
setStatus('fetched');
};
fetchData();
}, [url]);
return { status, data };
};
使用
const [query, setQuery] = useState('');
const url = query && `https://arvinxiang.com/api/v1/search?query=${query}`;
const { status, data } = useFetch(url);
记忆化获取的数据
const cache = {};
const useFetch = (url) => {
const [status, setStatus] = useState('idle');
const [data, setData] = useState([]);
useEffect(() => {
if (!url) return;
const fetchData = async () => {
setStatus('fetching');
if (cache[url]) {
const data = cache[url];
setData(data);
} else {
const response = await fetch(url);
const data = await response.json();
cache[url] = data; // set response in cache;
setData(data);
}
setStatus('fetched');
};
fetchData();
}, [url]);
return { status, data };
};
解决多个请求的性能问题
通过并行请求来加快速度
将所有请求放在 parent 一起执行(Promise.all),然后再将获得的数据传递给 children。
const useAllData = () => {
const [sidebar, setSidebar] = useState();
const [comments, setComments] = useState();
const [issue, setIssue] = useState();
useEffect(() => {
const dataFetch = async () => {
// waiting for allthethings in parallel
const result = (await Promise.all([fetch(sidebarUrl), fetch(issueUrl), fetch(commentsUrl)])).map((r) => r.json());
// and waiting a bit more - fetch API is cumbersome
const [sidebarResult, issueResult, commentsResult] = await Promise.all(result);
// when the data is ready, save it to state
setSidebar(sidebarResult);
setIssue(issueResult);
setComments(commentsResult);
};
dataFetch();
}, []);
return { sidebar, comments, issue };
};
const App = () => {
// all the fetches were triggered in parallel
const { sidebar, comments, issue } = useAllData();
// show loading state while waiting for all the data
if (!sidebar || !comments || !issue) return 'loading';
// render the actual app here and pass data from state to children
return (
<>
<Sidebar data={state.sidebar} />
<Issue comments={state.comments} issue={state.issue} />
</>
);
};
参考链接
https://www.smashingmagazine.com/2020/07/custom-react-hook-fetch-cache-data/ https://www.developerway.com/posts/how-to-fetch-data-in-react