Koala7 Koala7 - 22 days ago 6
React JSX Question

React - TypeError: Cannot read property 'map' of undefined

I am building a Charts Gallery using the Recharts library.

These are the files i am working on

The data fixtures is charts.js

const charts = [
{name: 'Page A', uv: 4000, pv: 2400, amt: 2400},
{name: 'Page B', uv: 3000, pv: 1398, amt: 2210},
{name: 'Page C', uv: 2000, pv: 9800, amt: 2290},
{name: 'Page D', uv: 2780, pv: 3908, amt: 2000},
{name: 'Page E', uv: 1890, pv: 4800, amt: 2181},
{name: 'Page F', uv: 2390, pv: 3800, amt: 2500},
{name: 'Page G', uv: 3490, pv: 4300, amt: 2100},
];

export default charts;


The data is correctly imported in my store with the rest of the other datas

Then i have my ChartsGrid.js where the error comes from

import React from 'react';
import Chart from './Chart';

export default class ChartsGrid extends React.Component{
render() {
return (
<div className="grid">
{this.props.charts.map((chart, i) => <Chart {...this.props} key={i} i={i} chart={chart} />)}
</div>
)
}
};


and here my chart component importing modules from the recharts library

import React from 'react';
import { Link } from 'react-router';
import { ResponsiveContainer, LineChart, Line, XAxis, YAxis, ReferenceLine,
ReferenceDot, Tooltip, CartesianGrid, Legend, Brush } from 'recharts';

export default class Chart extends React.Component {
render () {
const { chart, i} = this.props;
return (
<LineChart width={600} height={300} data={charts}
margin={{top: 5, right: 30, left: 20, bottom: 5}}>
<XAxis dataKey="name"/>
<YAxis/>
<CartesianGrid strokeDasharray="3 3"/>
<Tooltip/>
<Legend />
<Line type="monotone" dataKey="pv" stroke="#8884d8" activeDot={{r: 8}}/>
<Line type="monotone" dataKey="uv" stroke="#82ca9d" />
</LineChart>
);
}
};


Why is it throwing this error TypeError: Cannot read property 'map' of undefined ? What is actually undefined?

Answer

Looks like you have not imported the charts.js file before using the charts array.

You could import the charts.js file where you use the ChartsGrid component and pass charts as a prop:

import charts from './charts'
...
<ChartsGrid charts={charts} />

Or, you could use the charts object directly in ChartsGrid.js instead of this.props.

import charts from './charts'

export default class ChartsGrid extends React.Component{
  render() {
    return (
      <div className="grid">
        {charts.map((chart, i) => 
          <Chart {...this.props} key={i} i={i} chart={chart} />)}
      </div>
    )
  }
}

Note charts.map instead of this.props.charts.map because charts is directly imported in the file instead of being passed as a prop to the component (as in the 1st solution).

Comments