在反应中使用 async/await 未定义
Posted
技术标签:
【中文标题】在反应中使用 async/await 未定义【英文标题】:undefined using async/await in react 【发布时间】:2021-02-17 21:33:52 【问题描述】:我正在尝试使用 github api 来获取用户的项目并在弹出窗口中列出它们。我无法弄清楚为什么 async / await 不起作用并且我最终传递的数据始终未定义。
这就是我从 api 获取数据的方式(已编辑用于...):
export default async function GitHubFetch( userName )
let returnArray = [];
let response = await customFetch(
Urls.GitHub + "users/" + userName + "/repos"
);
for (const element of response)
let project = ;
project.name = element.name;
project.description = element.description;
project.html_url = element.html_url;
let langResponse = await customFetch(element.languages_url);
project.languages = Object.keys(langResponse);
returnArray.push(project);
console.log("the array i'm returning from fetch is: ", returnArray);
return returnArray;
这个函数的returnArray的console.log是:
["name":"cthulu_finance","description":"stock-trading application written in react and node.js / express","html_url":"https://github.com/contip/cthulu_finance","languages":["TypeScript","HTML","CSS"],"name":"c_structures","description":"collection of data structures in c","html_url":"https://github.com/contip/c_structures","languages":["C"],"name":"masm_io_procedures","description":"Low-level implementations of string-to-int and int-to-string in x86 assembly","html_url":"https://github.com/contip/masm_io_procedures","languages":["Assembly"]]
上述函数中的项目数组用于生成项目列表:
export default function GitHubListDisplay( projects )
let listItems = [];
console.log(projects);
if (Array.isArray(projects))
projects.forEach((project, index) =>
listItems.push(
<>
<ListGroup.Item action href=project.html_url>
project.name
</ListGroup.Item>
<ListGroup.Item>project.description</ListGroup.Item>
<ListGroup horizontal>HorizontalList(project.languages)</ListGroup>
</>
);
);
return <ListGroup>listItems</ListGroup>;
最后,这一切都由这个函数控制:
export default function GitHubPopUp( userName )
const [projectData, setProjectData] = useState([]);
useEffect(() =>
async function fetchData()
setProjectData(await GitHubFetch( userName ));
console.log("the project data i fetched is: ", projectData);
fetchData();
, []);
return (
<>
<OverlayTrigger
placement="right"
delay= show: 250, hide: 5000
overlay=
<Popover>
<Popover.Title as="h3">`GitHub Projects`</Popover.Title>
<Popover.Content>
<strong>userName's GitHub Projects:</strong>
projectData.length > 0 && (
<GitHubListDisplay ...projectData />
)
</Popover.Content>
</Popover>
>
<Button variant="link">userName</Button>
</OverlayTrigger>
</>
);
从主控制器功能,状态最终得到正确设置,但如果我在等待 Fetch 功能结果后直接控制台记录 projectData 状态,它是未定义的.. 结果是:
the project data i fetched is: []
此外,即使我有
projectData.length > 0 &&
在渲染 GitHubListDisplay 组件之前,console.logging 输入 projects
属性总是导致未定义。该函数永远不会显示任何内容。
有人可以帮忙吗?我花了令人尴尬的时间试图弄清楚这一点。
【问题讨论】:
forEach 内部使用的 'await' 永远不会阻塞主线程并执行 return 语句。所以你的 'GitHubFetch' 函数总是返回一个空数组。使用威廉指出的 promise.all()。 【参考方案1】:export default function GitHubPopUp( userName )
const [projectData, setProjectData] = useState([]);
useEffect(() =>
async function fetchData()
setProjectData(await GitHubFetch( userName ));
fetchData();
, []);
useEffect(() =>
console.log("the project data i fetched is: ", projectData);
, [ projectData ]);
return (
<>
<OverlayTrigger
placement="right"
delay= show: 250, hide: 5000
overlay=
<Popover>
<Popover.Title as="h3">`GitHub Projects`</Popover.Title>
<Popover.Content>
<strong>userName's GitHub Projects:</strong>
projectData.length > 0 && (
<GitHubListDisplay ...projectData />
)
</Popover.Content>
</Popover>
>
<Button variant="link">userName</Button>
</OverlayTrigger>
</>
);
【讨论】:
这适用于控制台。记录项目数据,但仍然无法将其传递给您不能按照自己的意愿将forEach
用于async await
。只需使用现代的 for … of
循环,其中 await 将按您的预期工作。
参考here
但是,最佳做法是使用Promise.all
【讨论】:
不幸的是,使用 for ... of 方法以及作为 Promise.all 的替代方法的 Array.prototype.reduce 方法仍然未定义/相同的行为来自同一个线程。我想确保这也可以:( 你能用 for...of 更新你的问题吗?并附上 returnArray 值 已更新.. 我也尝试使用 promise.all 得到相同的结果。虽然我不确定我是否正确使用它 我发现问题,添加userName依赖到使用效果 useEffect(() => ... , [ userName ]);以上是关于在反应中使用 async/await 未定义的主要内容,如果未能解决你的问题,请参考以下文章
嵌套的 try、catch 和 async、await 请求
使用带有 webpack-simple 配置的 async/await 抛出错误:RegeneratorRuntime 未定义