validateDOMNesting(...): <tr> 不能显示为问题的子项<div>



我在react.js项目中使用material-ui。当我尝试测试我的Row组件时,我得到了console.error:

Warning: validateDOMNesting(...): <tr> cannot appear as a child of <div>.

这是我的Row组件:

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>
</>
);
};

这里是为它生成的快照:

<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>

所以看起来问题出在<body>中的<div>元素上,但我不知道如何修复这个错误。我用React.Fragment(<>(来抓取这两个TableRow,所以在我看来<div>不应该存在。。。

我从material-ui文档中为可折叠表获取的Row组件:https://material-ui.com/components/tables/

还有代码沙盒代码(也来自文档(:https://codesandbox.io/s/material-demo-forked-fnisr?file=/demo.js

@@更新

我不得不用<table><tbody>包装Row组件。我已经为此创建了一个包装器。这就是测试代码现在的样子:

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();
});

在演示中,行被封装在表头或表体元素中,您还需要在组件中添加有效的上下文。

可以使用tr元素的上下文:

作为thead元素的子元素
作为tbody元素的子元素
作为tfoot元素的子元素
作为表元素的子元素,在任何caption、colgroup和thead元素之后,但前提是没有作为表元素子元素的tbody元素。

div不是来自自定义Row组件,而是来自渲染<Row />的位置。

tr元素必须具有父table元素。因此,用表包装组件将解决问题。

tr不能是div元素的后代。

只需用tbody 包装您的组件

例如,

<table>
<tbody>
<tr></tr>
<tr></tr>
</tbody>
</table>

最新更新