jsx 中的异步函数调用

Async function call inside jsx

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

这是一个有评论的组件,在我的数据库中,评论里面我只有authorId,所以我想调用getUser(authorId)函数来获取其他信息,比如[=16] =]、name

   /* 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;

你不能在 JSX 中调用异步函数,它会 return 一个 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();
}, []);
...

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

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} /> 
    </>
  );
}