在 React 中以正确的方式进行同步 API 调用 [重复]

Posted

技术标签:

【中文标题】在 React 中以正确的方式进行同步 API 调用 [重复]【英文标题】:Making synchronous API call the correct way in React [duplicate] 【发布时间】:2020-09-01 22:45:30 【问题描述】:

我正在导入到我的主文件中的另一个文件中有一个 API 调用。我想进行同步 API 调用,因为当响应可用时我不能使用 useState 挂钩来设置数据(因为 API 在另一个文件中......?)。我可以将 useState 挂钩传递给 API 吗?

我的印象是由于 async/await 的使用,promise 不会被返回。

截至目前,已解决的承诺正在返回到调用方文件:

从“../Static-codes/ErrorList”导入errorList;

export const retrieveBasicUserData = async (usernameFieldValue) => 
  const responseObject = 
    data: null,
    error: 
      exists: false,
      type: null,
    ,
  ;

  const response = await fetch(
    `https://api.github.com/users/$usernameFieldValue`
  );
  const responseJSON = await response.json();

  if (response.status == 404) 
    responseObject.error.exists = true;
    responseObject.error.type = errorList.userNotFoundError;
   else if (response.status === 200) 
    responseObject.data = responseJSON;
   else if (response.status !== 200 && response.status !== 404) 
    responseObject.error.exists = true;
    responseObject.error.type = errorList.apiGeneralError;
  
  console.log(responseObject);
  return responseObject;
;


let responseObject = retrieveBasicUserDataAPI(usernameFieldValue);
console.log(responseObject);

【问题讨论】:

【参考方案1】:

这是一种非常常见的模式,可以使用useEffectuseState 钩子的组合来解决。 useCallback 不是完全必要的,但记住回调没有坏处。

import doRetrieveBasicUserData from '.../'

const SomeComponent = ( userName ) => 
  const [loading, setLoading] = useState(false)
  const [userData, setUserData] = useState()

  const retriveBasicUserData = useCallback(async => 
    setLoading(true)
    const data = await doRetrieveBasicUserData(userName)
    setUserData(data)
    setLoading(false)
  , [doRetrieveBasicUserData])

  useEffect(_ =>  retrieveBasicUserData() , [])

  if (loading) return (<div>Loading ...<div>);
  return (
    <div>JSON.stringify(userData)</div>
  )

不只是这样做的原因:

useEffect(async => 
  setLoading(true)
  const data = await doRetrieveBasicUserData(userName)
  setData(data)
  setLoading(false)
, [doRetrieveBasicUserData])

... 是异步函数返回一个 Promise,useEffect 需要返回值是一个拆解函数,而不是一个 Promise。

【讨论】:

【参考方案2】:

即使调用是在另一个文件中定义的,但只要你能导入它,你应该可以通过

得到响应
  const abc = await retrieveBasicUserData(xxx)

调用是异步的,但是 async/await 组合会使它看起来像同步的。

【讨论】:

不能在异步之外使用等待

以上是关于在 React 中以正确的方式进行同步 API 调用 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

在 React-Router v4 中以编程方式导航

如何在 React js 中以表格格式显示 API 响应?

如何在 react-router 中以编程方式进行服务器端路由?

在 React 中以编程方式修改元素:在 CSS 规则之前

与同步服务器 API 的比较

node.js,express - 在循环中以同步方式一个接一个地执行mysql查询