& lt; div>不能作为<p>

我看到了这个。它在抱怨什么并不神秘:

Warning: validateDOMnesting(...): <div> cannot appear as a descendant of <p>. See ... SomeComponent > p > ... > SomeOtherComponent > ReactTooltip > div.

我是SomeComponentSomeOtherComponent的作者。但后者使用了外部依赖项(ReactTooltip from react-tooltip)。这可能并不一定是一个外部依赖,但它让我尝试在这里讨论它是“一些超出我控制的代码”。

鉴于嵌套组件工作正常(看起来),我应该对这个警告有多担心呢?无论如何,我该如何改变它(如果我不想重新实现一个外部依赖)?有没有我还不知道的更好的设计?

为了完整起见,下面是SomeOtherComponent的实现。它只是渲染this.props.value,当悬停时:一个写着“Some tooltip message”的工具提示:

class SomeOtherComponent extends React.Component {
constructor(props) {
super(props)
}


render() {
const {value, ...rest} = this.props;
return <span className="some-other-component">
<a href="#" data-tip="Some tooltip message" {...rest}>{value}</a>
<ReactTooltip />
</span>
}
}

谢谢你!

289819 次浏览

基于警告消息,组件ReactTooltip呈现一个HTML,看起来像这样:

<p>
<div>...</div>
</p>

根据这个文档<p></p>标记只能包含内联元素。这意味着在其中放置<div></div>标记是不合适的,因为div标记是一个块元素。不恰当的嵌套可能会导致像呈现额外的标签这样的小故障,这可能会影响你的javascript和css。

如果您希望消除此警告,您可能需要自定义ReactTooltip组件,或者等待创建者修复此警告。

我也有类似的问题,把组件包装成“div”而不是“p”,错误就消失了。

你的组件可以在另一个组件(比如<Typography> ... </Typography>)中呈现。因此,它将在<p> .. </p>中加载你的组件,这是不允许的。

< p >修复: 删除<Typography>...</Typography>,因为这只用于<p>...</p>或任何其他文本元素(如标题)中的纯文本。< / p >

如果在使用材质UI <Typography> https://material-ui.com/api/typography/时发生此错误,那么您可以通过更改<Typography>元素的component属性的值轻松地将<p>更改为<span>:

<Typography component={'span'} variant={'body2'}>

根据排版文档:

component:用于根节点的组件。使用DOM元素或组件的字符串。默认情况下,它将变体映射到一个良好的默认标题组件。

所以Typography选择<p>作为一个合理的默认值,你可以改变它。可能会有副作用…为我工作。

如果你正在寻找发生这种情况的地方,在控制台中你可以使用:document.querySelectorAll(" p * div ")

如果你正在使用ReactTooltip,为了让警告消失,你现在可以添加一个值为spanwrapper道具,如下所示:

<ReactTooltip wrapper="span" />

由于span是一个内联元素,它不应该再报错。

我通过使用材料界面组件得到了这个警告,然后我测试了component="div"作为下面代码的道具,一切都正确了:

import Grid from '@material-ui/core/Grid';
import Typography from '@material-ui/core/Typography';


<Typography component="span">
<Grid component="span">
Lorem Ipsum
</Grid>
</Typography>

实际上,这个警告发生是因为在Material UI中,Grid组件的默认HTML标记是div标记,而默认Typography HTML标记是p标记,所以现在警告发生了,

Warning: validateDOMnesting(...): <div> cannot appear as a descendant of <p>

细节 (以及一些关于警告的HTML理论) 显示<div> cannot appear as a descendant of <p>消息是因为< >强<p> < / >强标记的permitted content是根据设置为Phrasing Context的标准,其中不包括<div>标记。更多细节请参见链接。

我从React中<Card>组件的<Card.Text>部分中使用一个自定义组件得到了这个。我的组件都不在p标签中

这是浏览器的限制。你应该在App的渲染方法中使用div或article之类的东西因为这样你就可以在里面放任何你喜欢的东西。段落标记被限制为只包含一组有限的标记(主要是用于格式化文本的标记)。段落中不能有div

<p><div></div></p>

不是有效的HTML。根据规范中列出的标记省略规则,<p>标记由<div>标记自动关闭,这使得</p>标记没有匹配的<p>。浏览器可以通过在<div>之后添加一个开放的<p>标记来尝试纠正它:

<p></p><div></div><p></p>

你不能把<div>放在<p>中,并从不同的浏览器中获得一致的结果。为浏览器提供有效的HTML,它们将表现得更好。

你可以把<div>放在<div>中,所以如果你用<div class="p">替换你的<p>并适当地设置它的样式,你就可以得到你想要的。


细节 (以及一些关于警告的HTML理论) 显示<div> cannot appear as a descendant of <p>消息是因为< >强<p> < / >强标记的permitted content是根据设置为Phrasing Context的标准,其中不包括<div>标记。更多细节请参见链接。

警告出现只是因为演示代码有:

function TabPanel(props) {
const { children, value, index, ...other } = props;


return (
<div
role="tabpanel"
hidden={value !== index}
id={`simple-tabpanel-${index}`}
aria-labelledby={`simple-tab-${index}`}
{...other}
>
{value === index && (
<Box p={3}>  // <==NOTE P TAG HERE
<Typography>{children}</Typography>
</Box>
)}
</div>
);
}

像这样修改它就可以了:

function TabPanel(props) {
const {children, value, index, classes, ...other} = props;


return (
<div
role="tabpanel"
hidden={value !== index}
id={`simple-tabpanel-${index}`}
aria-labelledby={`simple-tab-${index}`}
{...other}
>
{value === index && (
<Container>
<Box>   // <== P TAG REMOVED
{children}
</Box>
</Container>
)}
</div>
);
}

当我在React中使用Chakra UI为一些文本做内联样式时,我得到了这个错误。进行内联样式化的正确方法是使用span元素,其他人对其他样式化框架也这么说。正确的代码:

<Text as="span" fontWeight="bold">
Bold text
<Text display="inline" fontWeight="normal">normal inline text</Text>
</Text>
我从React中使用一个组件的React -boostrap <Card.Text>部分得到了这个。我的组件都不在p标签中。& lt; Card.Text>默认情况下,在HTML树中显示为

,并且基本上有一个自定义React组件在__abc1中返回其jsx元素,这会导致<p><div>...</div></p>,这是一个糟糕的HTML。如果使用< card。text >你基本上可以像下面这样使用'as'属性 <Card.Text as='div'>,这将解决警告,因为它允许一个树,如<div><div></div></div>

App.js在渲染过程中有一个问题。 Don't use <div>...</div> to render just use <>...</>. < / p >

我解决了这个问题,通过删除我的标签,我用来包装我的2文本字段,导致相同的错误日志。

<div>不应该是<p>元素的后代,但<div>也不应该是__abc3元素的后代

错误: <p><div>Hi</div></p>

解决方案: <span><div>Hi</div></span>

我有同样的问题与react-bootstrap亚历克斯·C的解决方案,我发现我使用<div><Card.Text>,这是有点<p>

<Card.Text>
<div>{name}</div>
<div>{address}</div>
<div>{size}</div>
</Card.Text>

你不能是

的后代; 错误: <p><div>aaaa</div></p> 解决方案< / >强<div><p>aaaa</p></div>

材质UI !!!!!

我花了令人尴尬的时间,但多亏了这个答案——>在这里 by 亚历克斯·C给出了这个非常简单而聪明的解决方案

document.querySelectorAll(" p * div ")

所以令我惊讶的是,是材料界面 DialogContentText组件DialogContentText API导致了这个问题

因此,只需使用component={'span'}来解决问题(它不会影响样式)

 <DialogContentText id="alert-dialog-inputs" component={'span'}/>


< p >(额外) 问题可能是<p>元素内部的<p>元素在其他类似的错误

错误:

<p>
<p>
</p>
</p>