- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在为黑客新闻创建简单的克隆,我想使用 useEffect
并在其中返回 id,然后使用这些 id 获取前 50 个帖子。
问题在于 fetchHackerNewsPosts
中的第二个函数,它没有等待它在 postsArray
中添加数据,而是将其打印为空。
import React from "react";
import logo from "./logo.svg";
import "./App.css";
function App() {
const [posts, setPosts] = React.useState([]);
React.useEffect(() => {
let postsArray = [];
async function fetchHackerNewsPosts() {
try {
// it waits this function
let postsIDsArray = await fetch(
"https://hacker-news.firebaseio.com/v0/topstories.json"
)
.then((res) => res.json())
.then((result) => {
return result;
});
// it doesn't wait this function
await postsIDsArray.slice(0, 50).map((postId) => {
fetch(`https://hacker-news.firebaseio.com/v0/item/${postId}.json`)
.then((res) => res.json())
.then((result) => {
postsArray.push(result);
});
});
} catch (error) {
console.log(error);
}
}
fetchHackerNewsPosts();
console.log(postsArray);
}, []);
return (
<div className="p-10">
<header className="">
<h1> Hacker news API </h1>
</header>
<div className="bg-blue-600">list</div>
</div>
);
}
export default App;
最佳答案
我认为这里有两个问题。
1 - 您正在等待的函数不是异步函数。您正在执行 post postsIDsArray.slice(0, 50).map(...)
- 这只会解析为空数组(您不会返回提取)。您可以返回获取的内容,然后您将获得一组 promise ,然后您可以通过 Promise.all 等待:
await Promise.all(postsIDsArray.slice(0, 50).map((postId) => fetch(`https://hacker-news.firebaseio.com/v0/item/${postId}.json`)
.then((res) => res.json())
.then((result) => {
postsArray.push(result);
}));
这仍然会在您 console.log(postsArray);
的位置记录一个空数组 - 因为您没有等待 fetchHackerNewsPosts。
可能值得考虑使用所有等待/异步风格或所有 promise 风格,而不是混合两者。 ~~然而,这通常意味着切换到常规循环而不是map/forEach,所以你可以在中间等待。~~ - 编辑 - 删除,欢呼Lione
React.useEffect(() => {
async function fetchHackerNewsPosts() {
const posts = [];
try {
const postIDsResponse = await fetch(
"https://hacker-news.firebaseio.com/v0/topstories.json"
);
const postIDs = await postIDsResponse.json();
for (const postID of postIDs) {
const postResponse = await fetch(`https://hacker-news.firebaseio.com/v0/item/${postId}.json`);
const post = await post.json();
posts.push(post);
}
return posts;
} catch (error) {
console.log(error);
}
}
setPosts(await fetchHackerNewsPosts());
}, []);
正如所指出的 - Promise.all 实际上可能会快得多,因为您不需要等待上一个请求完成后再触发下一个请求。
React.useEffect(() => {
async function fetchHackerNewsPosts() {
try {
const postIDsResponse = await fetch(
"https://hacker-news.firebaseio.com/v0/topstories.json"
);
const postIDs = await postIDsResponse.json();
const postRequests = postIDs.map(async postID => {
const postResponse = await fetch(`https://hacker-news.firebaseio.com/v0/item/${postId}.json`);
return await post.json();
});
return await Promise.all(postRequests);
} catch (error) {
console.log(error);
}
}
const posts = await fetchHackerNewsPosts();
setPosts(posts);
}, []);
关于reactjs - 异步等待不等待 useEffect 内的响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63398305/
我知道没有数组的 useEffect() 只在第一次渲染时运行回调。 那么useEffect(()=>{},[])和没有useEffect()的区别是什么。 我的意思是: function myCom
我的场景很少,我想了解渲染和性能方面的差异。 下面显示的示例是一个简单的函数,但请考虑一个更复杂的函数以及一个异步函数。 场景 1:定义函数并在 useEffect 中调用它。 useEffect((
我需要添加一些与 React 之外的对象交互的事件处理程序(以 Google map 为例)。 在这个处理函数内部,我想访问一些可以发送给这个外部对象的状态。 如果我将状态作为依赖项传递给效果,它可以
要限制 useEffect 在第一个渲染上运行,我们可以这样做: const isFirstRun = useRef(true); useEffect (() => { if (isF
我有一个产品组件,它显示某个类别的产品。CategoryId 从路由参数中获取,然后用户可以对产品进行分页。所以有2个useEffect,一个是改变categoryId的时候,另一个是改变当前页码的时
我有一个产品组件,它显示某个类别的产品。CategoryId 从路由参数中获取,然后用户可以对产品进行分页。所以有2个useEffect,一个是改变categoryId的时候,另一个是改变当前页码的时
我的状态宽度随着窗口大小的调整而变化,showFilters作为 Prop 从true变为false。我想在卸载时删除监听器。因此,我为每个条件使用了三个 useState。那么,我可以做任何重构来在
我正在开发一个基于对象键管理字符串数组的函数。假设它看起来像这样: import React, { useState, useEffect } from "react"; import FieldCo
新的 React Hooks 功能很酷,但有时会让我感到困惑。特别是,我将此代码包装在 useEffect Hook 中: const compA = ({ num }) => { const [
我想将其转换为 useEffect钩: 代码 componentDidMount () { this.messagesRef.on('child_added', snapshot => {
这是我的代码部分。一切正常,但 eslint 给出错误。 React Hook useEffect has missing dependencies: 'dispatch' and 'getData'
当组件安装时,我需要从两个 API 端点获取数据。现在我有: useEffect(() => { dispatch(loadSomeDataOne()); }, [dispatch])
当组件安装时,我需要从两个 API 端点获取数据。现在我有: useEffect(() => { dispatch(loadSomeDataOne()); }, [dispatch])
在 React DOCs 中,关于 useEffect() 钩子(Hook),我们得到: “使用 useEffect 安排的效果不会阻止浏览器更新屏幕。” Tip Unlike componentDi
我一直试图了解何时取消订阅(useEffect 中的回调)被准确调用。 这是codepen链接:https://codepen.io/deen_john/pen/eYmNdMy 代码 : const
当对状态、效果、上下文等使用钩子(Hook)时,我这样做: import React, { useState, useEffect, useContext } from 'react'; 但是,我注意
我正在尝试像下面这样的 useEffect 示例: useEffect(async () => { try { const response = await fetch(`ht
我在我的 React 应用中构建了一个简单的点赞、书签功能。 const [liked, setLiked] = useState(); const [bookmarked, setBookmarke
我想了解为什么在代码块的底部使用 useEffect,以及它的用途。我认为它与组件生命周期和避免无限循环有关,但我无法完全理解它并全面了解这一切。如果有人能向我解释幕后发生的事情,以及 useEffe
useEffect(() => { return history.replace({ pathname: "path/A", }); }, []); useEffe
我是一名优秀的程序员,十分优秀!