繁体   English   中英

useState 与异步函数返回 Promise {<pending> }

[英]useState with async function returning Promise {<pending>}

所以,我知道这个问题已经被问了 100 次,但在我的例子中似乎没有一个解决方案有效。

我正在使用useState挂钩将状态更新为值initialValues ,该值获取从getInitialValues函数返回的数据

const [initialValues, setInitialValues] = useState(getInitialValues());

getInitialValues函数进行逻辑检查并返回一个对象或另一个函数retrieveDetails()

const getInitialValues = () => {
   let details;
   if(!addressDetails) {
      details = retrieveDetails();
   } else {
      details = { 
         ...,
         ...,
         ...
      };
   }
   return details;
}

函数retrieveDetails是一个进行API 调用的异步函数,我等待响应并返回从响应中接收到的对象。

const retrieveDetails = async () => {
   const addr = addressDetails[currentAddress];
   const { addressLookup } = addr;
   const key = process.env.API_KEY;
   const query = `?Key=${key}&Id=${addressLookup}`;
   const addrDetails = await new AddrService().getAddressDetails(query);
   return addrDetails;
}

但是,当我记录状态initialValues它返回Promise {<pending>}

即使删除 API 调用并简单地返回一个对象,也会呈现相同的结果。

不确定实际返回对象的最佳方法是什么?

任何帮助将不胜感激。

我不认为有一种方法可以异步获取初始数据到useState ,至少现在还没有。

React 不会等待您的数据到达,当您的异步操作排队(在事件循环端)时,该函数将继续运行直到完成。

当前惯用的方式是在效果中获取数据并更新状态。

useEffect(() => {
  getData(someParam).then(data => setState(data))
}, [someParam]) 

您可以在DOCS中阅读有关它的更多信息

这不是 React 内置的钩子支持的东西。

您需要构建或导入自定义挂钩。

想要简短而简单? 尝试这个:

const addressDetails = useAsyncFunctionResult(retrieveDetails);

并将其添加到 hooks/useAsyncFunctionResults.js

function useAsyncFunctionResult(asyncFunction, dependencies = []) {
  const [result, setResult] = React.useState();

  React.useEffect(() => {
    let mounted = true;
    asyncFunction().then((data) => mounted && setResult(data))
    return () => { mounted = false; }
  }, dependencies]);

  return result;
}

在第一次调用钩子时, retrieveDetails函数(问题中的那个)将开始执行(上面的().then位)。 结果一直保存到卸载。 卸载后更改组件状态不会出现任何错误。

如果您以后想添加缓存,请使用现有的钩子而不是自己制作。

React 中没有正式的 useAsync ,而且很可能永远不会,因为如果您的 Promise 发出请求并且请求组件在 Promise 解决之前确实卸载了,那么最佳实践是根据具体情况取消。

const retrieveDetails = async () => {
   const addr = addressDetails[currentAddress];
   const { addressLookup } = addr;
   const key = process.env.API_KEY;
   const query = `?Key=${key}&Id=${addressLookup}`;
   const addrDetails = await Promise.resolve(new AddrService().getAddressDetails(query))
   return addrDetails;
}


**try this once changed the function a bit**

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM