Reputation: 333
I am using material-ui
in my react.js
project. When I try to test my Row
component, I get that console.error
:
Warning: validateDOMNesting(...): <tr> cannot appear as a child of <div>.
Here is my Row
component:
const Row: React.FC<RowProps> = ({ course }) => {
const [open, setOpen] = useState(false);
const classes = useRowStyles();
const isDesktopOrLaptop = useMediaQuery({
query: '(min-device-width: 992px)',
});
const boxMargin = isDesktopOrLaptop ? 8 : 1;
return (
<>
<TableRow className={classes.root}>
<TableCell>
<IconButton
aria-label="expand row"
size="small"
onClick={() => setOpen(!open)}>
{open ? (
<KeyboardArrowUpIcon fontSize="large" />
) : (
<KeyboardArrowDownIcon fontSize="large" />
)}
</IconButton>
</TableCell>
<TableCell component="th" scope="row">
<Typography variant="h5" component="h5">
{course.course}
</Typography>
</TableCell>
<TableCell align="right">
<Typography variant="h5" component="h5">
{course.openedLessonsCount}
</Typography>
</TableCell>
</TableRow>
<TableRow>
<TableCell style={{ paddingBottom: 0, paddingTop: 0 }} colSpan={6}>
<Collapse in={open} timeout="auto" unmountOnExit>
<Box marginX={boxMargin} marginY={1}>
<Typography variant="h5" gutterBottom component="h5">
Projects
</Typography>
<Table size="small" aria-label="purchases">
<TableHead>
<TableRow>
<TableCell>
<Typography variant="h6" gutterBottom component="h6">
Name
</Typography>
</TableCell>
<TableCell align="right">
<Typography variant="h6" gutterBottom component="h6">
Completed Lessons
</Typography>
</TableCell>
</TableRow>
</TableHead>
<TableBody>
{course.projects &&
course.projects.map((project: IProject) => (
<TableRow key={project.project}>
<TableCell component="th" scope="row">
<Typography variant="body1" gutterBottom>
{project.project}
</Typography>
</TableCell>
<TableCell align="right">
<Typography variant="body1" gutterBottom>
{project.completedLessonsCount}
</Typography>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</Box>
</Collapse>
</TableCell>
</TableRow>
</>
);
};
And here is generated snapshot for it:
<body>
<div>
<tr
class="MuiTableRow-root makeStyles-root-1"
>
<td
class="MuiTableCell-root"
>
<button
aria-label="expand row"
class="MuiButtonBase-root MuiIconButton-root MuiIconButton-sizeSmall"
tabindex="0"
type="button"
>
<span
class="MuiIconButton-label"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root MuiSvgIcon-fontSizeLarge"
focusable="false"
viewBox="0 0 24 24"
>
<path
d="M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z"
/>
</svg>
</span>
<span
class="MuiTouchRipple-root"
/>
</button>
</td>
<th
class="MuiTableCell-root"
role="cell"
scope="row"
>
<h5
class="MuiTypography-root MuiTypography-h5"
>
Course1
</h5>
</th>
<td
class="MuiTableCell-root MuiTableCell-alignRight"
>
<h5
class="MuiTypography-root MuiTypography-h5"
>
3
</h5>
</td>
</tr>
<tr
class="MuiTableRow-root"
>
<td
class="MuiTableCell-root"
colspan="6"
style="padding-bottom: 0px; padding-top: 0px;"
/>
</tr>
</div>
</body>
So it looks like the problem is the <div>
element inside the <body>
, but I don't know how to fix that error. I use React.Fragment
(<>
) to grab these two of TableRow
, so that <div>
shouldn't exist in my opinion...
That Row
component I took from material-ui
docs for collapsible table:
https://material-ui.com/components/tables/
And there is codesandbox code for it (also from docs): https://codesandbox.io/s/material-demo-forked-fnisr?file=/demo.js
@@ UPDATE
I had to wrap Row component with <table>
and <tbody>
. I've created a wrapper for that. This is how the test code looks like now:
const Wrapper: React.FC = ({ children }) => {
return (
<table>
<tbody>{children}</tbody>
</table>
);
};
test('Basic render', () => {
const component = render(
<Wrapper>
<Row course={props} />
</Wrapper>
);
expect(component.baseElement).toMatchSnapshot();
});
Upvotes: 3
Views: 6934
Reputation: 119
Just wrap your component with tbody
For example,
<table>
<tbody>
<tr></tr>
<tr></tr>
</tbody>
</table>
Upvotes: 0
Reputation: 3226
In the demo the rows are wrapped in a table head or table body element, you need to add valid context in your component also.
Contexts in which a tr
element can be used:
As a child of a thead element.
As a child of a tbody element.
As a child of a tfoot element.
As a child of a table element, after any caption, colgroup, and thead elements, but only if there are no tbody elements that are children of the table element.
The parent div
is not from your custom Row
component, but from where you render <Row />
.
Upvotes: 1
Reputation: 85565
The tr
element must have parent table
element. So, wrapping your component with table will solve the issue.
The tr
cannot be descendent of div element.
Upvotes: 1