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

Why is the length of a non-empty array is 0

有一个代码,里面我通过数据创建链接并放入一个数组中:

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

当我安慰一个links:

为什么 links.length === 0 以及如何解决?

您需要使用两个反应钩子; useState 链接数组,useEffect 获取函数。

长话短说;博士 做以下更改:

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 是异步的,它不等待任何 Async 语句完成。因此,如果处理不当,本应在异步操作之后执行的下一行代码将执行。 forEach 方法不会连续执行您的异步代码(我猜这是您的假设)。所以在循环中,所有元素都会 运行 一个接一个(调用 fetch API),而不用等待前一个元素完成(这就是 JS 的工作方式)。 最后它到达下一行,即 console.log(links.length) 打印 0 因为你的 API 调用在执行此行之前从未完成。

Another important point :

在组件中执行这种代码是不可取的,因为每次状态更新和组件重新渲染时都会重新执行。 这种代码应该作为 sideEffect 执行,可能使用 useEffect 钩子。 这样代码块只在需要时执行,而不是每次渲染组件时都执行。