如何在React JSX中正确调用async异步函数getAuthor获取评论作者信息
问题原因
你直接在JSX中调用async函数getAuthor,async函数的返回值是Promise对象,而非你需要的作者信息,因此无法正常渲染对应内容,同时这种写法会导致每次组件重渲染都重复触发作者信息请求,性能极差。
解决方案
方案1:请求评论时批量补充作者信息(更推荐)
这种方案只需要批量请求一次所有作者信息,请求次数少,性能更好。修改useEffect中的逻辑,获取到评论后遍历补充作者信息再存入state:
useEffect(() => { const fetchMyData = async () => { const commentsFromDb = await getComments(); // 并行请求所有评论对应的作者信息,合并到评论对象中 const commentsWithAuthor = await Promise.all( commentsFromDb.map(async comment => { const author = await getUser(comment.authorId); return { ...comment, author }; }) ); setComments(commentsWithAuthor); }; fetchMyData(); }, []);
之后你就可以直接在JSX中读取合并后的作者信息,原代码中的getAuthor函数可以直接删除:
<p> author: {' '} {comment.author?.name} </p> <!-- 展示头像示例 --> <img src={comment.author?.profilePhoto} alt={comment.author?.name} />
这里用可选链?.是为了避免数据加载完成前访问属性报错,若你的开发环境不支持可选链,可以改用comment.author && comment.author.name的写法。
方案2:拆分单独评论项组件处理
如果评论数量非常多,你可以拆分出单独的CommentItem组件,每个组件内部单独请求自身对应的作者信息:
// 单独封装的评论项组件 function CommentItem({ comment }) { const [author, setAuthor] = useState(null); useEffect(() => { const loadAuthor = async () => { const authorData = await getUser(comment.authorId); setAuthor(authorData); }; loadAuthor(); }, [comment.authorId]); return ( <div className="comment"> <p> author: {' '} {author ? author.name : '加载中...'} </p> <p> subject: {' '} {comment.subject} </p> <p> date: {' '} {comment.date} </p> <p> message: {' '} {comment.message} </p> <p> o: {' '} {comment.placeId} </p> </div> ); }
然后修改原Comments组件的渲染逻辑即可:
{comments .filter(comment => comment.placeId === placeId) .reverse() .map(comment => ( // 记得给列表项添加唯一key,避免React渲染警告,这里假设评论有唯一id字段 <CommentItem key={comment.id} comment={comment} /> ))}
内容的提问来源于stack exchange,提问作者ciekawyziemniak
相关产品推荐
相关产品推荐

