如何在 React 中使用 useEffect hook 和 async/await 检索嵌套的 JSON 数据

Posted

技术标签:

【中文标题】如何在 React 中使用 useEffect hook 和 async/await 检索嵌套的 JSON 数据【英文标题】:How to retrieve nested JSON data with useEffect hook and async/await in React 【发布时间】:2019-11-23 04:18:43 【问题描述】:

我需要与 contentful 集成,并且很难获取嵌套的 JSON 数据

当我这样做时,我得到了想要的结果:


  const client = contentful.createClient(
    space: '<space_id>',
    accessToken: '<access_token>'
  );

  useEffect(async () => 
    const response = await client.getEntry(id);
    setHeadLinks(response.fields.slug);
  , []);

  console.log(headLinks);

不过,我在控制台中收到警告:

警告:效果函数不能返回除用于清理的函数之外的任何内容。

看起来你写了 useEffect(async () => ...) 或返回了一个 Promise。相反,在你的效果中编写异步函数并立即调用它:

useEffect(() => 
  async function fetchData() 
    // You can await here
    const response = await MyAPI.getData(someId);
    // ...
  
  fetchData();
, [someId]); // Or [] if effect doesn't need props or state

所以当我尝试它时,我收到一条错误消息,指出未定义响应:

useEffect(() => 
    const fetchData = async () => 
      const response = await client.getEntry(id);
    ;
    setHeadLinks(response.fields.slug);
    fetchData();
  , []);

  console.log(headLinks);

感谢您的帮助

【问题讨论】:

【参考方案1】:

您将调用移至函数外的setHeadLinks,因此response 变量不在范围内。只需要把它移回里面:

useEffect(() => 
  const fetchData = async () => 
    const response = await client.getEntry(id);
    setHeadLinks(response.fields.slug);
  ;
  fetchData();
, []);

【讨论】:

非常感谢!本可以发誓我做到了,但我显然没有。【参考方案2】:

这是因为response 是在async 函数的块内定义的。尝试在 async 函数范围之外定义 response 以利用闭包。

useEffect(async () => 
  let response;
  const fetchData = async () => 
    response = await client.getEntry(id);
  ;
  await fetchData();
  setHeadLinks(response.fields.slug);  
, []);

请特别注意,您需要使用let 而不是const。你也有使用async/await 的问题。请参阅更正后的示例并查看下面的链接以获取有关所提及主题的更多信息。

https://developer.mozilla.org/en-US/docs/Glossary/Scope

https://developer.mozilla.org/es/docs/Web/javascript/Closures

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function

这应该可以解决您当前的错误,但我不知道这是否足以满足您的要求。

【讨论】:

以上是关于如何在 React 中使用 useEffect hook 和 async/await 检索嵌套的 JSON 数据的主要内容,如果未能解决你的问题,请参考以下文章

如何在 useEffect 中使用 setTimeout 重置 React 钩子状态

如何在 React 中使用 useEffect 挂钩调用多个不同的 api

如何在 React useEffect 中更改路由器

React:如何通过 Firestore onSnapshot 和 useEffect 使用最新状态?

如何使用/不使用 useEffect 钩子在 React JS 函数中获取更改的(新)状态值?

使用 Jest 和酶时如何在 React.useEffect 钩子上获得线路覆盖?