yush
yush

Reputation: 426

ReactJS: Cannot Read Property 'map' of Undefined

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

Answers (3)

Prakash Jethava
Prakash Jethava

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

Paul Martin
Paul Martin

Reputation: 469

I've tried to recreate this with some numbers as incidents. The issues I see are...

  1. Your DisplayOpenIncidents component doesn't have a return statement, so the AccordionExample component isn't being rendered.
  2. Your forEach function doesn't return anything, so the component won't render. Running map will fix this.
  3. You're passing a state from a parent to a child, then setting the state in the child. You don't need to do 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

Deepu Reghunath
Deepu Reghunath

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

Related Questions