简体   繁体   English

在反应中使用异步/等待未定义

[英]undefined using async/await in react

I'm trying to use the github api to get a user's projects and list them in a popup window.我正在尝试使用 github api 来获取用户的项目并在弹出窗口中列出它们。 I'm having trouble figuring out why async / await isn't working and the data i end up passing is always undefined.我无法弄清楚为什么 async / await 不起作用,并且我最终传递的数据始终未定义。

This is how i fetch the data from the api (edited to use for... of):这就是我从 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;
}

the console.log of returnArray from this function is:这个函数的 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"]}]

the array of projects from the above function is used to generate the list of projects by this:来自上述函数的项目数组用于通过以下方式生成项目列表:

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>;
}

and finally, it's all controlled by this function:最后,这一切都由这个函数控制:

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>
    </>
  );
}

From the main controller function, the state eventually gets set correctly, but if i console.log the projectData state directly after awaiting the Fetch function result, it's undefined.. result is:从主控制器函数来看,状态最终会被正确设置,但是如果我在等待 Fetch 函数结果后直接控制台.log projectData 状态,它是未定义的..结果是:

the project data i fetched is:  []

Additionally, even though i have {projectData.length > 0 && before rendering the GitHubListDisplay component, console.logging the input projects property always results in undefined.此外,即使在呈现 GitHubListDisplay 组件之前我有{projectData.length > 0 && ,console.logging 输入projects属性总是导致未定义。 The function never ends up displaying anything.该函数永远不会显示任何内容。

Can anyone please help?有人可以帮忙吗? I've spent an embarrassing number of hours trying to figure this out.我花了令人尴尬的几个小时试图弄清楚这一点。

You cannot use forEach indeed for async await as you desire.您不能根据需要将forEach用于async await Just use a modern for … of loop instead, in which await will work as you expected.只需使用现代for … of循环代替,其中 await 将按您的预期工作。

Refer to here参考这里


However, best practice is to use Promise.all但是,最佳实践是使用Promise.all

 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> </> ); }

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

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