简体   繁体   English

为什么非空数组的长度为0

[英]Why is the length of a non-empty array is 0

There is a code, in it I create links by data and put into an array:有一个代码,在其中我通过数据创建链接并放入一个数组中:

function Blogs(props) {
    const links = [];
    props.ids.forEach(id => {
        fetch(`${root}/api/blog/${id}`)
            .then(res => res.json())
            .then(res => {
                const link = <Link to={`/blog/${id}`}>{_.get(res, 'blog.name', '')}</Link>
                links.push(link);
            })
    });
    console.log(links.length) // 0
    return (
        <div className="profile-blogs">
            <div className="a">Блоги</div>
            <div className="b">
                {links}               {/* nothing */}
            </div>
        </div>
    );
}

When I consoling a links :当我安慰links时:

在此处输入图像描述

Why links.length === 0 and how to fix it?为什么links.length === 0以及如何解决它?

TL;DR do below changes: TL;DR 进行以下更改:

async function Blogs(props) {
  const links = [];
  for(let id of props.ids){
       const res = await fetchLink(id);
       const link = <Link to={`/blog/${id}`}>{_.get(res, 'blog.name', '')}</Link>
       links.push(link);
  }
  const fetchLink = async(id) =>{
    const result = await  fetch(`${root}/api/blog/${id}`);
    return result.json();
  }
  console.log(links.length) // 0
  return (
      <div className="profile-blogs">
          <div className="a">Блоги</div>
          <div className="b">
              {links}               {/* nothing */}
          </div>
      </div>
  );
}

But Why my code is not working?但是为什么我的代码不起作用?

JS is asynchronous, it doesn't wait for any Async statement to finish. JS 是异步的,它不会等待任何 Async 语句完成。 So if not handled properly, the next line of code which is intended to be executed after the async operation will execute.因此,如果处理不当,将执行异步操作之后要执行的下一行代码。 forEach method will not execute your async code serially (I guess that is your assumption). forEach方法不会连续执行您的异步代码(我猜这是您的假设)。 So in the loop, all the element will run one by one (calling the fetch API) without waiting for the previous one to get completed(that is how JS works).所以在循环中,所有元素将一个一个地运行(调用fetch API),而无需等待前一个元素完成(这就是 JS 的工作方式)。 Finally it reaches to the next line ie console.log(links.length) which prints 0 because your API call never finished before executing this line.最后它到达下一行,即console.log(links.length)打印0因为您的 API 调用在执行此行之前从未完成。

Another important point:另一个重要的点:

Executing this kind of code in the component is not advisable because it will be re-executed every time the state is updated and component is re-rendered.不建议在组件中执行此类代码,因为每次更新 state 并重新渲染组件时都会重新执行它。 Such kind of code should be executed as sideEffect probably using the useEffect hook.这种代码应该作为sideEffect执行,可能使用useEffect钩子。 So that the code block is only executed when needed and not every time the component is rendered.这样代码块仅在需要时执行,而不是每次渲染组件时执行。

You need to use two of the react hooks;您需要使用两个反应钩子; useState for links array, useEffect for fetch function. useState用于链接数组, useEffect用于获取 function。

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

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