如何在react中返回异步组件

问题描述 投票:0回答:1
import { AuthContext } from "../../App";
import {useContext, useEffect} from 'react';
import axios from 'axios';

export default function Assignments({ clicked }) {
    const { loggedIn } =  useContext(AuthContext);
    let elements = [];


    (async () => {
        if (loggedIn) {
            try {
                const result = await axios.get('http://localhost:2000/database/assignments');
                const qids = result.data["assignments"];
                const result2 = await axios.post('http://localhost:2000/database/questions', {
                      assignments: qids
                }, { headers: {'Content-Type': 'Application/json' } });


                const questions = result2.data["assignments"];
                console.log(questions);
                console.log('questions[0]:',  questions[0]);
                console.table(questions);
                // Updating Assignments
                if (questions) {
                    console.log("extraced questions correctly");
                    elements = questions.map( assignment =>
                        <>
                            <div key={assignment.qid} className="p-6 bg-white border border-gray-200 rounded-lg shadow dark:bg-gray-700 dark:border-gray-700">
                                <a href={'#'}> {/* Should go to the '/codeground/:qid' route */}
                                    <h5 className="mb-2 text-2xl font-bold tracking-tight text-gray-900 dark:text-white">{assignment.heading}</h5>
                                </a>
                                <p className="mb-3 font-normal text-gray-700 dark:text-gray-400">{assignment.description}</p>
                                <a href={`#`} className="inline-flex items-center px-3 py-2 text-sm font-medium text-center text-white bg-blue-700 rounded-lg hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800">
                                    Open Assignment
                                    <svg className="w-3.5 h-3.5 ml-2" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 10">
                                        <path stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M1 5h12m0 0L9 1m4 4L9 9"/>
                                    </svg>
                                </a>
                            </div>
                        </>
                    );

                }
            } catch (err) {
                console.log(err);
            }
        }
    })();

    console.log('this is out of async');

    useEffect(() => {
        console.log('reassigned assignments');
        console.log(elements);
    }, [loggedIn]);


    if (elements) {
        return (
            <>
                <div className="flex flex-col gap-y-4 mt-1.5">
                    { elements }
                </div>
            </>
        );
    }
    return (
        <>Not yet loaded</>
    );
}

我正在尝试呈现从数据库中获取的问题。 我知道数据库运行良好,并且

elements
变量正在更新。问题是 Component 函数返回得太早。

return (
        <>Not yet loaded</>
    );

即使在数据库获取和更新元素之前,该函数也会返回

Not yet loaded
。 我是一个刚刚开始反应的初学者,提示会对我有所帮助。

reactjs asynchronous
1个回答
0
投票

在效果中执行查询,将结果放入状态中,将该状态映射到元素中。

我建议使用

useSWR
钩子让这对你来说更简单,但如果没有它:

import { AuthContext } from "../../App";
import { useContext } from "react";
import axios from "axios";

async function getQuestions() {
  const result = await axios.get("http://localhost:2000/database/assignments");
  const qids = result.data["assignments"];
  const result2 = await axios.post(
    "http://localhost:2000/database/questions",
    {
      assignments: qids,
    },
    { headers: { "Content-Type": "Application/json" } },
  );
  const questions = result2.data["assignments"];
  return questions;
}

export default function Assignments({ clicked }) {
  const { loggedIn } = useContext(AuthContext);
  const [questions, setQuestions] = useState(null);
  React.useEffect(() => {
    if (loggedIn) {
      getQuestions().then(setQuestions);
    }
  }, [loggedIn]);

  if (questions === null) {
    return <>Loading...</>;
  }

  return (
    <div className="flex flex-col gap-y-4 mt-1.5">
      {questions.map((q) => (
        <div key={q.qid}>rest elided ...{q.qid}</div>
      ))}
    </div>
  );
}
© www.soinside.com 2019 - 2024. All rights reserved.