I have the following component which is being called from a container component. The container component passes the transactions prop.

I know that the data property in prop is being passed in fine and has data and can be accessed from the console.log call. However, when I try to map the data and create the list, I get an error: Cannot read property 'map' of undefined

Here is what the data looks like:

[
{"transid":3426,"acct":"acct1","category":"Auto"},
 {"transid":3427,"acct":"acct2","category":"Subscriptions"}
]

What am I doing wrong?

import React from 'react';


export default function TransactionManagerView (props) {

  console.log(props.data);

  return (
    <ul>
      {
        props.data.map(function(el,index) {
           return <li key={index}>{el.category}</li>
        })
      }
    </ul>
  )

}

Solution 1

Provide a check for undefined prop.data and then render the component because it is possible that the props initially don't provide the data but is available in the second render. That should solve your problem

class App extends React.Component {
  render() {
    var data = [
{"transid":3426,"acct":"acct1","category":"Auto"},
 {"transid":3427,"acct":"acct2","category":"Subscriptions"}
]
    return (
        <div ><TransactionManagerView data={data}/></div>
    )
  }

}



const TransactionManagerView = function(props) {

  console.log(props.data);

  return (
    <ul>
      {
        props.data && props.data.map(function(el,index) {
           return <li key={index}>{el.category}</li>
        })
      }
    </ul>
  )

}

ReactDOM.render(<App/>, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react-dom.min.js"></script>
<div id="app"></div>

Solution 2

It is because the rendering of component occurs before the component receives the array. As an option, you can set the default value of a prop

import React from 'react';


export default function TransactionManagerView ({data = [], ...props}) {

  console.log(props.data);

  return (
    <ul>
      {
        data.map(function(el,index) {
           return <li key={index}>{el.category}</li>
        })
      }
    </ul>
  )

}