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 callrenderCell
function which will return array of JSX element to be push insiderenderBody
method.renderCell
: This method usesfor
in
to 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>
)
}
CodePudding user response:
To render an array of JSX elements, you should be able to do this:
renderCell = (row) => {
return row.map(cell => {
return <TableCell key={i} align="right">{ row[prop] }</TableCell>
}
}
CodePudding user response:
Edit:
<TableBody>
{(pagination
? rows.slice(page * rowsPerPage, page * rowsPerPage rowsPerPage)
: rows
).map((row) => {
return (
<TableRow
onClick={onRowClicked(row)}
hover
role="checkbox"
tabIndex={-1}
key={row[props.rowsUniqueKey]}
>
{columns.map((column) => {
const value = row[column.id];
return (
<>
<TableCell
key={column[props.columnsUniqueKey]}
align={column.align}
>
{column.format && typeof value === 'number'
? column.format(value)
: value}
</TableCell>
</>
);
})}
{/* { enableActions && <TableCell> Actions </TableCell> } */}
</TableRow>
);
})}
</TableBody>
from: Create dynamic action column in React Material UI Table