Home > Software engineering >  Render Array of JSX element inside Helper function
Render Array of JSX element inside Helper function

Time:09-17

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 call renderCell function which will return array of JSX element to be push inside renderBody method.
  • renderCell: This method uses for 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

  • Related