I am having an issue rendering a React functional component when included as subcompnent in a parent component.
The following renders perfectly:
<Table title="Actions">
<TableHeaderCell>Name</TableHeaderCell>
<TableHeaderCell>Description</TableHeaderCell>
<TableHeaderCell>Start Date</TableHeaderCell>
{data.data.map(item => (
<TableRow>
<TableCell>
{item.name}
</TableCell>
<TableCell>
{item.activity_type.description}
</TableCell>
<TableCell>
{item.startDate}
</TableCell>
</TableRow>))}
</Table>
However, when replacing the TableRow with a functional component, then the TableRow is never shown. I created the following Subcomponent:
export const ActivityRowComponent = props => {
console.log('entered ActivityRowComponent');
const item = props.activityItem;
return (
<TableRow>
<TableCell>
{item.name}
</TableCell>
<TableCell>
{item.activity_type.description}
</TableCell>
<TableCell>
{item.startDate}
</TableCell>
</TableRow>
);
};
ActivityRowComponent.propTypes = {
activityItem: PropTypes.object.isRequired,
};
and changed the code from above to:
<Table title="Actions">
<TableHeaderCell>Name</TableHeaderCell>
<TableHeaderCell>Description</TableHeaderCell>
<TableHeaderCell>Start Date</TableHeaderCell>
{data.data.map(item => (
<ActivityRowComponent key={item.activity_id} activityItem={item} />
))}
</Table>
Note that the "console.log" in "ActivityRowComponent" is never reached. Also, if I set a breakpoint I can observe that "ActivityRowComponent" is never called. And, note that the array data.data has a length of 1.
Any ideas what I am doing wrong? What to do in order for the ActivityRowComponent to be rendered?
I've reproduced your scenario at CodeSandbox using HTML table.
And your component is rendering OK. Changed a bit though.
Please check.
Related
I am having an issue where I can't seem to get TransitionGroup to work with Material UI ReactJS library
My expectation is pretty simple, upon entry into the table the row should be animated in like sliding into the table.
I have tried the following but this only end up scattering the table, the headers and everything becomes out of shape.
Here is what I have tried using the Material UI library for ReactJS
<TableContainer>
<Table aria-label="stats-table">
<TableHead>
<TableRow>
{...}
</TableRow>
</TableHead>
<TransitionGroup
transitionName="fade"
transitionEnterTimeout={1000}
transitionLeaveTimeout={300}
transitionAppearTimeout={1000}
transitionAppear={true}
component="tbody">
<TableBody>
{
(rowsPerPage > 0 ? games.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) : games
).map((row: Game) => (
<SimpleTableRow row={row} key={row.id}/>
))}
{
emptyRows > 0 && (
<TableRow style={{height: 53 * emptyRows}}>
<TableCell colSpan={6}/>
</TableRow>
)
}
</TableBody>
</TransitionGroup>
</TableContainer>
The moment I add the TransitionGroup, the entire table headers and body becomes scattered.
How can I make this work? Thanks
You can try to pass component={null} instead component="tbody".
I was using the older version of React Table for last couple of months and now when i started using Latest version v7, i started facing difficulty in customizing the table while no data is found in the table to be displayed. It doesn't show any message like 'No Rows Found' which was earlier displayed in previous versions of the table. How could i render the noDataComponent.
As v7 is headless, you are responsible for the output under the varying conditions. You likely have something like map() in place to iterate over the data array similar to:
<TableBody>
{page.map((row) => {
prepareRow(row);
return (
<TableRow {...row.getRowProps()}>
{row.cells.map((cell) => {
return (
<TableCell {...cell.getCellProps()}>
{cell.render('Cell')}
</TableCell>
);
})}
</TableRow>
);
})}
</TableBody>
You can add some code to detect the condition where no rows are found similar to:
{page.length === 0 &&
<TableRow>
<TableCell>
No data to display
</TableCell>
</TableRow>
}
I have a requirement to show popovers, when clicking on table cell (used Material UI table cell). Tried adding onclick function to cell, but not able to pass the element value to the function. How can I achieve this? Below is the code snippet which used to render table.
<TableBody>
{dataObject.map((data) => (
<TableRow key={data.id}>
<TableCell>
<Button>
{data.info}
</Button>
</TableCell>
<TableCell>
{data.request}
</TableCell>
</TableRow>
))}
</TableBody>
Thanks in advance.
The <TableCell> component is eventually a td/th in your html, so you don't really have a value attached to it (it's not like a pure react component that you can just use value, or an input element that has value that you can access).
What you can do is access the element's innerHTML / textContent to access the content of the cell using the event itself:
const handleCellClick = (e) => {
console.log(e.target.textContent);
}
<TableCell onClick={handleCellClick}>{data.request}</TableCell>
Having a simple react Component:
<Table>
<TableBody>
<TableCell>
x
</TableCell>
</TableBody>
</Table>
How can I conditionally enclose the TableBody in yet another component (e.g. Paper)? I thought of something like the below, but this does not seem to do it.
<Table>
{paper && <Paper>}
<TableBody>
<TableCell>
x
</TableCell>
</TableBody>
{paper && </Paper>}
</Table>
If you want to avoid repeating the code for the Table body, you can assign it to a variable and use that.
const content = (
<TableBody>
<TableCell>
x
</TableCell>
</TableBody>
);
return (
<Table>
{paper ? <Paper>{content}</Paper> : content}
</Table>
)
You can do it this way. I considered null condition for paper variable, you can do it with any.
<Table>
{paper !== null ? (
<Paper>
<TableBody>
<TableCell>
x
</TableCell>
</TableBody>
</Paper>
):(<TableBody>
<TableCell>
x
</TableCell>
</TableBody>)}
</Table>
I have an issue with react material-UI's table component.
I wanna create a table where the content is shown dynamically based on the data it receives. So I'm looping through the data, each time creating a new TableBody as the root element. But when I'm looping through the data, it only displays the first (or maybe the last) cycle in the loop.
Here is my code from the render method (the code is vastly simplified):
<Table selectable={ false }>
<TableHeader displaySelectAll={false} adjustForCheckbox={false}>
<TableRow>
<TableHeaderColumn colSpan={3}>{ this.i18n('Filename') }</TableHeaderColumn>
</TableRow>
</TableHeader>
{
files.map((file, idx) => (
<TableBody displayRowCheckbox={ false } key={idx}>
<TableRow>
<TableRowColumn>{ file.name }</TableRowColumn>
<TableRowColumn colSpan={2}><Button variant="flat" data-name='cancel' color="primary">{ this.i18n('Delete') }</Button></TableRowColumn>
</TableRow>
<TableRow />
<TableRow>
<TableRowColumn colSpan={3}>
<RadioButtonGroup name='caption' />
<RadioButton />
<RadioButton />
</RadioButtonGroup>
<Input type='text' />
</TableRowColumn>
</TableRow>
</TableBody>
))
}
</Table>
This only outputs one cycle in the in the loop, even though the data contains several loops.
NOTE::: The code works, when I replace the material-UI with a html table, then it works as expected.
this is because you create a tableBody every item loop, try to set the loop right after < TableBody > tag, because you want to loop < TableRow > not < TableBody >