I have a parent functional component named Dashboard and a child class component named DashboardTable. I'm making a graphql call in the parent class and want to pass the result into the child like this <DashboardTable data={opportunityData}/>.
problem: I can get see the data in the parent but its not showing in the child
Here is my code. Please let me know what I'm doing wrong
Dashboard
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;
}
const [opportunityTable, changeOpportunityTable] = useState(asyncCall());
console.log(opportunityTable); // this works! returns a promise
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>
);
}
DashboardTable
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() {
super();
this.state = {
opportunityData: this.props,
};
}
render() {
console.log(this.opportunityData); // this doesnt work :( no data
return (
<div>
<div
className="row row-cols-1 row-cols-md-2 mx-auto"
style={{ maxWidth: 900 }}
>
{this.opportunityData.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" }}
>
{opportunity.level}
</span>
<span
className="badge bg mb-2"
style={{ margin: 2, backgroundColor: "#ff9900" }}
>
{opportunity.ShadowReverse}
</span>
</div>
</div>
</div>
))}
</div>
</div>
);
}
}
export default DashboardTable;
CodePudding user response:
There are some bugs in the child like this.state.opportunityData = this.props, that end part should likely be this.props.opportunityData, however to get you going with the async call in the parent component give this a try
const [opportunityTable, changeOpportunityTable] = useState([]);
async function asyncCall() {
const gqlreturn = await API.graphql({
query: queries.listMockOppsTables,
});
changeOpportunityTable(gqlreturn);
}
useEffect(() => asyncCall(), []);
CodePudding user response:
Few pointers
Call api on mount in parent's useEffect
In child directly use the passed property in child
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>
);
}
class DashboardTable extends React.Component {
constructor() {
super();
//this.state = {
// opportunityData: this.props,
//};
}
render() {
console.log(this.props.data); // this doesnt work :( no data
return (
<div>
<div
className="row row-cols-1 row-cols-md-2 mx-auto"
style={{ maxWidth: 900 }}
>
//map thru data prop {this.props.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" }}
>
{opportunity.level}
</span>
<span
className="badge bg mb-2"
style={{ margin: 2, backgroundColor: "#ff9900" }}
>
{opportunity.ShadowReverse}
</span>
</div>
</div>
</div>
))}
</div>
</div>
);
}
}
Hope it helps