繁体   English   中英

React:如何在渲染子组件之前等待道具数据

[英]React: How to wait on prop data before rendering child component

我有一个名为 Dashboard 的父组件和一个名为 DashboardTable 的子组件。 我能够在父元素中成功进行异步 graphql 调用并将数据传递给子组件。

问题:props 数据需要一秒钟来加载,所以它在获取数据之前返回 undefined 一秒钟(使用 console.log() 验证)。 该延迟导致映射 function 中出现错误。错误:无法读取未定义的属性(读取“映射”)

问题:如何让渲染器在渲染前等待道具数据加载。 我尝试了这样的条件{this.props.data == undefined? (wait): (render)} {this.props.data == undefined? (wait): (render)}但这没有用(同样的错误)。

这是我的代码。 请让我知道我做错了什么

仪表板表(子)

import React from "react";
import "bootstrap/js/src/collapse.js";
import Navigation from "../Navigation";
import { Link } from "react-router-dom";
import { API } from "@aws-amplify/api";
import config from "../../aws-exports";
import * as queries from "../../graphql/queries";

export class DashboardTable extends React.Component {
  constructor(props) {
    super(props);
  }

 

  render() {
    console.log(this.props.data.data); // !!this returns undefined one time then a second later it returns the props data I want :)

    return (
      <div>
        <div
          className="row row-cols-1 row-cols-md-2 mx-auto"
          style={{ maxWidth: 900 }}
        >
          {this.props.data.data.map((opportunity) => (
            <div className="col mb-4">
              <div>
                <a href="#">
                  <img
                    className="rounded img-fluid shadow w-100 fit-cover"
                    src="assets/img/products/awsLogo.jpg"
                    style={{
                      height: 250,
                    }}
                  />
                </a>
                <div className="py-4">
                  <span
                    className="badge mb-2"
                    style={{ margin: 2, backgroundColor: "#ff9900" }}
                  >
                    {opportunity.interview_type}
                  </span>
                  <span
                    className="badge bg mb-2"
                    style={{ margin: 2, backgroundColor: "#ff9900" }}
                  >
                    4
                  </span>
                  <span
                    className="badge bg mb-2"
                    style={{ margin: 2, backgroundColor: "#ff9900" }}
                  >
                    Reverse
                  </span>
                </div>
              </div>
            </div>
          ))}
        </div>
      </div>
    );
  }
}
export default DashboardTable;


仪表板(父级)这有效。 它将 graphql 数据传递给孩子

import React, { useEffect, useState } from "react";
import "bootstrap/js/src/collapse.js";
import DashboardTable from "../DashboardTable";
import { API } from "@aws-amplify/api";
import config from "../../aws-exports";
import * as queries from "../../graphql/queries";

export default function Dashboard() {
  API.configure(config);

  async function asyncCall() {
    const gqlreturn = await API.graphql({
      query: queries.listMockOppsTables,
    });
    // console.log(gqlreturn.data.listMockOppsTables); // result: { "data": { "listTodos": { "items": [/* ..... */] } } }
    return gqlreturn;
  }

  // initialize with empty array
  const [opportunityTable, changeOpportunityTable] = useState([]);
  //console.log(opportunityTable); // this works! returns a promise

  // call api to fetch data on mount
  useEffect(() => {
    const fetchData = async () => {
      const response = await asyncCall();

      changeOpportunityTable(response);
    };

    fetchData();
  }, []);

  return (
    <div>
      <section className="py-5 mt-5">
        <div className="container py-5">
          <h2 className="fw-bold text-center">
            Your upcoming shadowing events
            <br />
            <br />
          </h2>

          <DashboardTable data={opportunityTable}></DashboardTable>
        </div>
      </section>
    </div>
  );
}

你需要这样做:

{ oppotrunityTable && opportynityTable.length ?
  <DashboardTable data={opportunityTable}></DashboardTable>
  : null
}

但是你有一个错误,不是因为这个而是因为你的数据是未定义的! 检查你的数据!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM