【问题标题】:Async function call inside jsxjsx内部的异步函数调用
【发布时间】:2023-03-22 16:41:01
【问题描述】:

我尝试调用getAuthor 函数,在function (line 24 -console.log) 内部一切正常,但我不知道应该如何正确调用getAuthor 函数(第37 行)。

这是一个带有评论的组件,在我的数据库中,评论记录里面我只有authorId,所以我想调用getUser(authorId)函数来获取其他信息,比如profilePhotoname等。

   /* eslint-disable jsx-a11y/click-events-have-key-events */
/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */
/* eslint-disable no-underscore-dangle */
/* eslint-disable import/no-cycle */
/* eslint-disable jsx-a11y/anchor-is-valid */
import React, { useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import { getComments, getUser } from '../../actions/FetchData';
import '../../scss/base/_comments.scss';
import CommentForm from './CommentForm/CommentForm';

function Comments({ placeId }) {
  const [comments, setComments] = useState([]);
  useEffect(() => {
    const fetchMyData = async () => {
      const commentsFromDb = await getComments();
      setComments(commentsFromDb);
    };
    fetchMyData();
  }, []);

  const getAuthor = async (authorId) => {
    const authorFromDb = await getUser(authorId);
    console.log(authorFromDb.profilePhoto);
    return authorFromDb;
  };

  return (
    <>
      <h1>Komentarze</h1>
      <div className="comments">
        {comments.filter((comment) => comment.placeId === placeId).reverse().map((comment) => (
          <div className="comment">
            <p>
              author:
              {' '}
              {getAuthor(comment.authorId)}
            </p>
            <p>
              subject:
              {' '}
              {comment.subject}
            </p>
            <p>
              date:
              {' '}
              {comment.date}
            </p>
            <p>
              message:
              {' '}
              {comment.message}
            </p>
            <p>
              o:
              {' '}
              {comment.placeId}
            </p>
          </div>
        ))}
      </div>
      <CommentForm placeId={placeId} />
    </>
  );
}

Comments.propTypes = {
  placeId: PropTypes.string.isRequired,
};

export default Comments;

【问题讨论】:

    标签: javascript reactjs asynchronous react-hooks jsx


    【解决方案1】:

    我建议当您让 cmets 映射 cmets 并向作者请求 cmets 时,然后向您的评论对象添加一个代表作者的新属性,然后在渲染中您可以轻松访问作者属性

    import "./styles.css";
    import { useEffect, useState } from "react";
    
    export default function App() {
      const [comments, setComments] = useState([]);
      const placeId = 1;
    
      async function getComments() {
        return [
          {
            placeId: 1,
            authorId: 1,
            subject: "subject",
            date: "21-2-2020"
          }
        ];
      }
    
      async function getUser(id) {
        return { profilePhoto: "Hi there", name: "Ob616" };
      }
    
      useEffect(() => {
        getComments().then(async (commentsFromDb) => {
          for (let index = 0; index < commentsFromDb.length; index++) {
            const comment = commentsFromDb[index];
    
            comment.author = await getAuthor(comment.authorId);
          }
    
          console.log(commentsFromDb);
          setComments(commentsFromDb);
        });
      }, []);
    
      const getAuthor = async (authorId) => {
        const authorFromDb = await getUser(authorId);
        console.log(authorFromDb.profilePhoto);
        return authorFromDb;
      };
    
      return (
        <>
          <h1>Komentarze</h1>
          <div className="comments">
            {comments
              .filter((comment) => comment.placeId === placeId)
              .reverse()
              .map((comment) => (
                <div className="comment">
                  <p>author: {comment.author.name}</p>
                  <p>subject: {comment.subject}</p>
                  <p>date: {comment.date}</p>
                  <p>message: {comment.message}</p>
                  <p>o: {comment.placeId}</p>
                </div>
              ))}
          </div>
    
          <CommentForm placeId={placeId} /> 
        </>
      );
    }
    
    
    

    【讨论】:

    • 我认为这是一个很好的解决方案,但是当我尝试保存 cmets“setComments(cmetsFromDb)”时我仍然遇到问题,在“commnents”中我有 Promise,我怎样才能得到 PromiseResult? (承诺已兑现)
    • 试试这个useEffect(() =&gt; { let mounted = true; getComments().then(commentsFromDb =&gt; { if (mounted) { commentsFromDb = commentsFromDb.map(async comment =&gt; { comment.author = await getAuthor(comment.authorId) return comment; }) setComments(commentsFromDb); } }); return () =&gt; mounted = false; }, []);
    • 还是这样
    • 检查这个代码沙箱,我让它在那里工作SandBox
    • 说实话,我不明白这个沙盒的解决方案。它肯定是正确的代码版本吗?您在哪里将“作者”添加到“评论”中,例如此处的“comment.author = await getAuthor(comment.authorId)”等?
    【解决方案2】:

    你不能在 JSX 中调用异步函数,它会返回一个 Promise。你必须先解决承诺。

    一种解决方案是与comments 做同样的事情,(把它放在useEffect 钩子上)

    像这样:

    ...
    const [comments, setComments] = useState([]);
    const [author, setAuthor] = useState([]);
    useEffect(() => {
      const fetchMyData = async () => {
        const commentsFromDb = await getComments();
        setComments(commentsFromDb);
        const authorFromDb = await getAuthor(commentsFromDb.authorId);
        setAuthor(authorFromDb );
      };
      fetchMyData();
    }, []);
    ...
    

    【讨论】:

      猜你喜欢
      • 2018-11-17
      • 1970-01-01
      • 2013-12-07
      • 1970-01-01
      • 2018-09-06
      • 1970-01-01
      • 2015-11-29
      • 2017-04-07
      • 1970-01-01
      相关资源
      最近更新 更多