自定义react hook获取并存储数据

创建 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

© 2022  Arvin Xiang
Built with ❤️ by myself