Reputation: 426
I have a parent component that fetches data and stores it into useState which then gets passed into a child component as a prop.
When that child component gets rendered, I store that prop data into useState which I try and then iterate over with a map or forEach function but I get cannot read property of undefined errors
when checking React Dev tools, the array that gets passed from Parent to child exists so im not too sure what im doing wrong.
Parent Component:
const DisplayOpenIncidents = () => {
const [data, setData] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
const incidents = FetchIncidents();
incidents.then((incidents) => {
setData(incidents);
setLoading(false);
});
}, []);
return (
<AccordionExample data={data} />
);
};
Child Component:
const AccordionExample = (props) => {
const [test, setTest] = useState(props.data);
useEffect(() => {
console.log(props.data); // Displays array
setTest(props.data);
}, [props]);
return (
<Accordion defaultActiveKey="0">
<Card>
<Accordion.Toggle as={Card.Header} eventKey="0">
TITLE
</Accordion.Toggle>
<Accordion.Collapse eventKey="0">
<Card.Body>
{test.forEach((test) => {
console.log(test);
})}
</Card.Body>
</Accordion.Collapse>
</Card>
</Accordion>
);
};
TIA
Upvotes: 1
Views: 260
Reputation: 200
Basically, you have to put check when using test object like bellow
<Accordion.Collapse eventKey="0">
<Card.Body>
{test ? test.forEach((test) => {
console.log(test);
}) : "Error"}
</Card.Body>
</Accordion.Collapse>
Upvotes: 1
Reputation: 469
I've tried to recreate this with some numbers as incidents. The issues I see are...
DisplayOpenIncidents
component doesn't have a return statement, so the AccordionExample
component isn't being rendered.forEach
function doesn't return anything, so the component won't render. Running map
will fix this.Here's the code working with a substitute error array...
import React, { useState, useEffect } from "react"
const AccordionExample = (props) => {
return (
<div defaultActiveKey="0">
<div>
<div eventKey="0">
TITLE
</div>
<div eventKey="0">
<div>
{props.data.map((test) => <p>{test}</p>)}
</div>
</div>
</div>
</div>
);
};
const App = () => {
const [data, setData] = useState([]);
useEffect(() => {
const incidents = [1, 2, 3]
//incidents.then((incidents) => {
setData(incidents);
//setLoading(false);
//});
}, []);
return (<AccordionExample data={data} />);
}
export default App
Upvotes: 1
Reputation: 9713
use the condition as follows
<Accordion.Collapse eventKey="0">
<Card.Body>
{test && test.forEach((test) => {
console.log(test);
})}
</Card.Body>
</Accordion.Collapse>
Upvotes: 2