Introduction:
I'm trying to create Table Component which can reusable in nature. It can contain any number of column as per data pass to it through props from parent component.
In order to achieve this, I've created separate function as below to populate JSX element according.
renderColumn: It take column name pass as props of array of string from parent.renderBody: This will populate body and TableRow of each row. It will the callrenderCellfunction which will return array of JSX element to be push insiderenderBodymethod.renderCell: This method usesforinto iterate each property of row object and create TableCell element and pushing it to array and returning the array which ideally contain JSX element.
Problem Statement:
However, I'm unable to push JSX element return from renderCell method inside renderBody method.
I did tried console logging the element it return from renderCell method which seems like JSX element only.
Components:
src\components\Table\index.js
import Table from '@material-ui/core/Table';
import TableBody from '@material-ui/core/TableBody';
import TableCell from '@material-ui/core/TableCell';
import TableContainer from '@material-ui/core/TableContainer';
import TableRow from '@material-ui/core/TableRow';
renderCell = (row) => {
var cell = [];
var i = 1;
for (var prop in row) {
if (row.hasOwnProperty(prop)) {
cell.push(<TableCell key={i} align="right">{ row[prop] }</TableCell>);
i++;
}
}
console.log(cell)
return cell;
}
renderBody = () => {
let rows = this.props.rows
return (
<TableBody>
{rows.map( row => {
<TableRow key={row.key}>
{ this.renderCell(row) } // How do I render Array of JSX Element?
</TableRow>
})}
</TableBody>
)
}
render() {
return (
<TableContainer>
<Table aria-label="simple table">
{ this.renderColumn() }
{ this.renderBody() }
</Table>
</TableContainer>
);
}
Below is console.log from renderCell function
[
{
$$typeof: Symbol(react.element)
key: "1"
props: {align: 'right', children: 1}
ref: null
type: {$$typeof: Symbol(react.forward_ref), propTypes: {…}, Naked: {…}, options: {…}, render: ƒ, …}
_owner: FiberNode {tag: 1, key: null, stateNode: Table, elementType: ƒ, type: ƒ, …}
_store: {validated: false}
_self: Table {props: {…}, context: {…}, refs: {…}, updater: {…}, renderColumn: ƒ, …}
_source: {fileName: '/path/src/components/Table/index.js
},
]
Complete SandBox link
Data:
[
{
"key": 1,
"launch_date_utc": "2006-03-24T22:30:00.000Z",
"location": "Kwajalein Atoll",
"mission_name": "FalconSat",
"orbit": "LEO",
"launch_success": false,
"upcoming": false,
"rocket_name": "Falcon 1"
},
{...}
]
Edit 1: Failed to compile
When trying to wrap inner for loop inside map() function as per following question. It is not compiling by without using renderCell method.
renderBody = () => {
return (
<TableBody>
{this.props.rows.map( row => {
<TableRow key={row.key}>
{
for (var prop in row) {
if (row.hasOwnProperty(prop)) {
<TableCell align="right">{ row[prop] }</TableCell>
}
}
}
</TableRow>
})}
</TableBody>
)
}