TL;DR
do below changes :
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. 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). 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).
Finally it reaches to the next line i.e console.log(links.length)
which prints 0
because your API call never finished before executing this line.
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.
Such kind of code should be executed as sideEffect
probably using the useEffect
hook.
So that the code block is only executed when needed and not every time the component is rendered.