【问题标题】:Why is the length of a non-empty array is 0为什么非空数组的长度为0
【发布时间】:2021-04-19 18:44:52
【问题描述】:

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

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 以及如何解决它?

【问题讨论】:

  • fetch()异步.then() 函数将在 HTTP 请求完成时运行。
  • 您的console.log 写在之后 fetch 但实际上fetch之后调用 因为它需要时间来获取.. . 所以代码移动到console.log,而fetch 代码仍在等待数据。这是一个简化的解释。
  • 你需要看this

标签: javascript reactjs lodash


【解决方案1】:

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

但是为什么我的代码不起作用?

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

另一个重点:

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

【讨论】:

  • 不是你应该如何在 React 中异步获取和渲染。
  • @EmileBergeron 同意了。见我的最后一段。我更正代码的第一个是让他了解异步代码的工作原理。这绝对不是 React 的做法。
  • 不幸的是,这会让您的回答产生误导。
【解决方案2】:

你需要使用两个 react 钩子; useState 用于链接数组,useEffect 用于获取功能。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-06-23
    • 2018-03-26
    • 2014-07-27
    • 2017-12-20
    • 2017-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多