Passing an array attribute of an object as a React component prop throws an exception

  javascript, reactjs

I’m trying to understand why I can not pass an array attribute of a data object into a Component as a prop. Think this is a fundamental understanding question of how React works, and/or the pitfalls in a case like this…any insight is appreciated!

Context: I’m working on a Show page for a Meeting in React. This Show page will show elements like "title", "description", as well as iterate through a list of "agenda_items".

The data comes from a single JSON API response. "agenda_items" is a nested array within the data structure.

{
  data: {
    id: 2,
    title: "Example title",
    description: "Example description",
    agenda_items: [
      {
        id: 5,
        title: "Topic 1"
      },
      {
        id: 6,
        title: "Topic 2"
      }
    ]
  }
}

The below implementation works. I am setting meeting and agenda_items separately with React.useState(), even though agenda_items is theoretically accessible via meeting.agenda_items.

const Meeting = () => {
  const [meeting, setMeeting] = React.useState([]);
  const [agenda_items, setAgendaItems] = React.useState([]);

  const handleFetchMeeting = React.useCallback(() => {
    axios
      .get(url)
      .then(result => {
        setMeeting(result.data);
        setAgendaItems(result.data.agenda_items);
      })
  });

  React.useEffect(() => {
    handleFetchMeeting();
  }, []);

  return (
    <div>
      <h1>{meeting.title}</h1>
      <AgendaList list={agenda_items} />
    </div>
  );
}

const AgendaList = ({ list }) => {
  return (
    <div>
      <h3>Agenda</h3>
      {list.map(item => (
        <Item 
          key={item.id}
          item={item}
        />
      ))}
    </div>
  );
}

However, if I instead try to pass meeting.agenda_items into the <AgendaList> as a param, it throws an exception. I would’ve thought these two implementations are equivalent, but it seems not?

...

return (
    <div>
      <h1>{meeting.title}</h1>
      <AgendaList list={meeting.agenda_items} />
    </div>
  );
)

//INSTEAD OF
/*
return (
    <div>
      <h1>{meeting.title}</h1>
      <AgendaList list={agenda_items} />
    </div>
  );
)
*/

Uncaught TypeError: Cannot read property 'map' of undefined
    at AgendaList (Meeting.jsx:52)
    at renderWithHooks (react-dom.development.js:14972)
    at mountIndeterminateComponent (react-dom.development.js:17734)
    at beginWork (react-dom.development.js:18935)
    at HTMLUnknownElement.callCallback (react-dom.development.js:3922)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:3971)
    at invokeGuardedCallback (react-dom.development.js:4031)
    at beginWork$1 (react-dom.development.js:23780)
    at performUnitOfWork (react-dom.development.js:22616)
    at workLoopSync (react-dom.development.js:22553)

How is it that React has no problem with finding/rendering {meeting.title}, but then calls {meeting.agenda_items} undefined?

Source: Ask Javascript Questions

LEAVE A COMMENT