Reputation: 430
In my code below onDataChange
prop of Form element
fetches data from .CSV to JSON via Papa.parse
in Form
Component and updates data
in state of CommonComponent
.
While loading data after choosing .CSV file Keys: Object.keys(this.props.data[0])
shows error that this.props.data[0]
is null
. However, {this.props.data.map(data=> <TableRows key={data.id} {...data}/>)}
works fine and waits for data
to be updated and rendered, even if both of them where null
in the beginning.
Is there any way to handle this situation? I want to use Object.keys(this.props.data[0])
(i.e. The keys of Array's first object) to show table headers because for different .CSV table header will be different, and i want to render table for any size or scale .CSV.
Here's my code, I haven't shown Form
component because, it's irrelevant.
const TableRows = (props) => {
return (
<tr>
<td>{props.Account_Created}</td>
<td>{props.City}</td>
<td>{props.Country}</td>
<td>{props.Last_Login}</td>
</tr>
);
};
class TableComponent extends Component {
state = {
Keys: []
};
componentDidMount() {
this.setState({
Keys: Object.keys(this.props.data[0])
})
}
render() {
return (
<div>
<table border="1">
<thead>
<tr>
{this.state.Keys.map(KEY => <th>{KEY}</th>)}
</tr>
</thead>
<tbody>
{this.props.data.map(data=> <TableRows key={data.id} {...data}/>)}
</tbody>
</table>
</div>
);
}
}
class CommonComponent extends Component {
state = {
data: []
};
updateData = (result) => {
const data = result.data;
this.setState({data});
};
render() {
return (
<div>
<Form onDataChange={this.updateData}/>
<TableComponent data={this.state.data}/>
</div>
);
}
}
Upvotes: 0
Views: 1196
Reputation: 430
I got the solution, Now i can show any JSON data coming to TableComponent
via props. This is the solution for my problem, i came up after considering reply from chbchb55:
class TableRows extends Component {
render() {
return (
<tr>
{this.props.keys.map(Key=> <td>{this.props.data[Key]}</td>)}
</tr>
);
}
}
class Table extends Component {
render() {
return (
<table>
<thead>
<tr>
{this.props.keys.map(Key => <th>{Key}</th>)}
</tr>
</thead>
<tbody>
{this.props.data.map(data=> <TableRows key={data.id} keys={this.props.keys} data={data}/>)}
</tbody>
</table>
);
}
}
class TableComponent extends Component {
render() {
return (
<div>
<Table keys={this.props.data.length > 0 ? Object.keys(this.props.data[0]) : []} data={this.props.data}/>
</div>
);
}
}
Upvotes: 1
Reputation: 5075
componentDidMount
You're problem is that you're using componentDidMount
to obtain the keys
from the data object. When the component mounts there most likely won't be data yet.
Solution: Get the keys in render
. This will work better for two reasons:
Here is the code:
render() {
return (
<div>
<table border="1">
<thead>
<tr>
{ this.props.data.length > 0 ? Object.keys(this.props.data[0]).map(KEY => <th>{KEY}</th>) : ''}
</tr>
</thead>
<tbody>
{this.props.data.map(data=> <TableRows key={data.id} {...data}/>)}
</tbody>
</table>
</div>
);
}
Upvotes: 1