Reputation: 3580
I have a connected React component called Dashboard, which should be populated with Plot components. These components should be created by mapping an array of JSON objects, retrieved and placed into state via an API call, and then mapped to props through a function, mapStateToProps().
The API call is working. mapStateToProps is also working. However, my attempt to map the array of plot JSON objects in props and create a Plot component from each one fails, with the following error: Cannot read property 'map' of undefined
I suspect that what is going on is that, since I have put the relevant mapping code into the render() lifecycle hook, the code is attempting to run before the API call returns. So, there is no property in state for what it's trying to do when it's trying to do it. Is this the case? If so, how can I fix it?
My Plot component:
import React from 'react';
const Plot = ({ props }) => {
return (
<div className="media">
<div className="media-left">
<a href="#">
<img className="media-object" src="http://placehold.it/200/550" alt="Placehold" />
</a>
</div>
<div className="media-body">
<h4 className="media-heading">{props.name}</h4>
<ul>
<li><strong>Grower: </strong> {props.grower}</li>
<li><strong>Region: </strong> {props.region}</li>
<li><strong>Current State: </strong> {props.currentState}</li>
<li><strong>Next State: </strong> {props.nextState}</li>
<li><strong>Days To Next State: </strong> {props.daysToNext}</li>
<br />
<span class="pull-right">
<i id="like1" class="glyphicon glyphicon-thumbs-up"></i> <div id="like1-bs3"></div>
<i id="dislike1" class="glyphicon glyphicon-thumbs-down"></i> <div id="dislike1-bs3"></div>
</span>
</ul>
</div>
</div>
);
};
export default Plot;
My Dashboard component:
import React, { Component } from 'react';
import { connect } from 'react-redux';
import * as actions from '../actions';
import Plot from './plot';
class Dashboard extends Component {
componentWillMount() {
this.props.fetchMessage();
this.props.fetchPlots();
}
render() {
const plots = this.props.plots;
return (
<div>
<span>{this.props.message}</span>
<div className='container'>
{plots.map((plot) => <Plot name={plot.name} grower={plot.grower} region={plot.region} currentState={plot.currentState} nextState={plot.nextState} daysToNext={plot.daysToNext}/>)}
</div>
</div>
);
}
}
function mapStateToProps(state)
{
return {
message: state.auth.message,
plots: state.auth.plots
}
}
export default connect(mapStateToProps, actions)(Dashboard);
Upvotes: 2
Views: 1889
Reputation: 830
{plots && plots.map((plot) =>
<Plot
name={plot.name}
grower={plot.grower}
region={plot.region}
currentState={plot.currentState}
nextState={plot.nextState}
daysToNext={plot.daysToNext}
/>
)}
Just append a null check before the map function so that it executes only if it has data
Upvotes: 4