【问题标题】:React wait for fetch data as part of custom hookReact 等待获取数据作为自定义钩子的一部分
【发布时间】:2021-08-21 15:59:20
【问题描述】:

在我的 React 功能组件中,我有以下代码;

const user = useFetch('api/userinfo', {});

本质上,这是一个自定义钩子调用,在内部它有一个对 API 的 fetch 调用并设置数据(下面是 usefetch 中的相关代码);

const [data, setData] = useState(initialData);
//....fetch call
setData(json); // once data is fetched

在我的主要组件中,由于我的网格依赖于这些数据,我如何让代码等待继续到 Grid jsx 直到获取数据?我打算使用 async..await。但不确定是否可以在这里使用自定义钩子来做到这一点?


使用下面的代码,似乎由于某种原因,钩子被多次调用;

export default function useFetch(initialUrl, initialData) {
  const [url] = useState(initialUrl);
  const [loadingData, setLoadingData] = useState(true);
  const [data, setData] = useState(initialData);
  useEffect(() => {
    setLoadingData(true);
    fetch(url)
      .then(response => {
        if (response.status === 200) {
          response.json().then(json => {
            setData(json);
            setLoadingData(false);
          });
      })
  }, [url]);

  return [loadingData, data];
}

【问题讨论】:

  • 我会设置一个加载状态,在获取开始时将其设置为 true,在成功获取数据或出现错误后将其设置为 false。然后在你的 jsx 中不显示网格,直到加载状态为 false

标签: reactjs react-hooks react-functional-component


【解决方案1】:

几个选项供您选择:

  1. 使用另一个状态变量(即一些布尔值)并使用它来跟踪数据是否从 API 返回。然后有条件地渲染一些“加载”元素

  2. 检查数据是否存在并根据其存在有条件地呈现。

【讨论】:

  • 非常感谢。另一个状态变量会在自定义钩子代码中吗?任何参考都会非常有帮助。
  • 没有其他状态会在等待钩子的组件中
【解决方案2】:

以下是使用自定义挂钩的方法:

// defining useFetch hook
const useFetch = (url) => {
  // state to keep track of loading
  const [loadingData, setLoadingData] = useState(false);

  // state for data itself
  const [data, setData] = useState(null);

  // effect to fetch data
  useEffect(() => {
    const fetchData = async () => {
      try {
        // set data to loading
        setLoadingData(true);

        // request to load data, you can use fetch API too
        const { data } = await axios.get(url);

        // set data in state and loading to false
        setLoadingData(false);
        setData(data);
      } catch (error) {
        console.log("error", error);
      }
    };

    fetchData();
  }, [url]);

  // return the data and loading state from this hook
  return [loadingData, data];
};

现在,您可以在组件中使用此钩子,例如:

const MyComponent = (props) => {
  const [isDataLoading, data] = useFetch('/api/some-url');

  // now check if data is loading, if loading then return a loader/spinner
  if (isDataLoading || !data) return <p>Data is loading...</p>

  // otherwise render your actual component
  return (
    <div>
      <h1>This is my component with data</h1>
    </div>

  );
}

【讨论】:

  • 非常感谢...但是由于某种原因,由于某种原因,挂钩被多次调用...。在主要问题中添加了整个代码...。不确定我是否在做出了点问题……
  • @testndtv 首先,您的useEffect 中有语法错误,修复它,它应该可以正常工作。为什么在你的钩子中使用useState 代替url?我认为没有必要这样做。我没有测试上面的代码 ^ 当我写的时候,只是测试了它并且工作正常
猜你喜欢
  • 2022-01-07
  • 2022-01-01
  • 2020-06-20
  • 1970-01-01
  • 2020-04-21
  • 2023-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多