javascript - 在我自己的钩子(Hook)中使用 fetch - 在 return() 中显示加载程序

标签 javascript reactjs

useFetch 钩子(Hook):

import React, { useState, useEffect } from 'react';

const useFetch = (url, options) => {
  const [response, setResponse] = useState(null);
  const [error, setError] = useState(null);

  useEffect(() => {
    (async () => {
      try {
        const res = await fetch(url, options);
        const json = await res.json();
        setResponse(json);
      } catch (error) {
        setError(error);
      }
    })();
  }, [url]);

  return { response, error };
};

export default useFetch;

然后我在我的组件中使用这个钩子(Hook):

const Example = () => {
  const res = useFetch('some_URL');

  if (!res.response) {
    return <div>Loading...</div>;
  }
  const data = res.response.data;

  return (
    <>
      ...Mapping data array here, also i want to show loader here.
    </>
  )
}

如您所见,在自定义 Hook 内使用 fetch() ,我必须显式检查 if (!res.response) 否则,我将得到一个错误认为 data 未定义。我可以将加载器设置在 return() 中,这样它看起来会更干净吗?

我还应该为获取方法使用自定义 Hook 吗?或者最好将其用作普通函数?

我的组件的更新部分

const Example = () => {
  const res = useFetch('some_URL');
  const data = res.response.data;

  return data ? (
    <>
      {
        data.map(......);
      }
    </>
  ) : (
    <>Loading...</>
  );
}

这给了我一个错误:无法读取 null 的属性“data”并完全停止渲染。

最佳答案

我会做这样的事情:

const Example = () => {
    const { response, error } = useFetch('some_URL');

    return (response ?
        <div>{response.data}</div> :
        <div>Loading...</div>
    );
}

或者使用useMemo Hook 以使其更具可读性和优化性:

const Example = () => {
    const { response, error } = useFetch('some_URL');

    const content = useMemo(() => {
        if (response) {
            return response.data;
        } else {
            return 'Loading...';
        }
    }, [response]);

    return (
        <div>{content}</div>
    );
}
<小时/>

这是一个为特定数据获取创建专用钩子(Hook)的示例:

用户.js

import React, { useState, useEffect } from 'react';

export const useUserData = id => {
    const [userData, setUserData] = useState(null);

    useEffect(() => {
        (async () => {
            try {
                const res = await fetch('/users/', { id });
                const json = await res.json();
                setUserData(json);
            } catch (error) {
                setUserData(undefined);
            }
        })();
    }, [id]);

    return userData;
}

示例.jsx

import React from 'react';
import { useUserData } from 'users';

export default Example = () => {
    const userData = useUserData(1);

    return (userData ?
        <div>{userData.name}</div> :
        <div>Loading...</div>
    );
}

关于javascript - 在我自己的钩子(Hook)中使用 fetch - 在 return() 中显示加载程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60033897/

相关文章:

javascript - React hooks 的使用效果

javascript - 按单选按钮值过滤 ng-repeat

javascript - 无法在 Android 设备上运行 React-Native 示例代码

javascript - 将 es6 map 的内容转换为 JSON 数组

reactjs - 对 useEffect 的多次调用 - React

reactjs - 如何在React中实现进度条?

javascript - 如何仅在用户开始向下滚动后才显示标题? [ react ]

javascript - 创建拖放卡时无法读取未定义的属性 'map'

javascript - 更改下拉列表中所选选项的颜色

javascript - Jquery UI 日期选择器如何