为什么非空数组的长度是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
钩子。
这样代码块只在需要时执行,而不是每次渲染组件时都执行。
有一个代码,里面我通过数据创建链接并放入一个数组中:
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
钩子。
这样代码块只在需要时执行,而不是每次渲染组件时都执行。