<div>不能作为<p>的后代出现

San*_*gen 59 reactjs

我看到了这个.它抱怨的是什么并不神秘:

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

我的作者SomeComponentSomeOtherComponent.但后者正在使用外部依赖(ReactTooltip来自react-tooltip).这可能不是必需的,这是一个外部依赖,但它让我尝试这里的论点,它是"一些不受我控制的代码".

考虑到嵌套组件工作得很好(貌似),我应该多担心这个警告?无论如何我都会如何改变它(假设我不想重新实现外部依赖)?有没有更好的设计,我还没有意识到?

为了完整起见,这里是实现SomeOtherComponent.它只是呈现this.props.value,并在悬停时:一个工具提示,上面写着"一些工具提示消息":

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>
  }
}
Run Code Online (Sandbox Code Playgroud)

谢谢.

JD *_*dez 56

根据警告消息,组件ReactTooltip呈现的HTML可能如下所示:

<p>
   <div>...</div>
</p>
Run Code Online (Sandbox Code Playgroud)

根据该文档,<p></p>标签只能包含内联元素.这意味着在其中放置一个<div></div>标签应该是不合适的,因为div标签是一个块元素.不正确的嵌套可能会导致毛刺,如渲染额外的标签,这可能会影响您的JavaScript和CSS.

如果要删除此警告,可能需要自定义ReactTooltip组件,或等待创建者修复此警告.

  • 我想是的,因为它是在w3c推荐中.此外,我们可以轻松地用`span`替换`div`以避免这种警告,但不会影响代码逻辑中的任何内容. (2认同)
  • 尝试在 &lt;p&gt; 中使用 &lt;span&gt; 而不是 &lt;div&gt; - 这应该可以修复它。我在使用 &lt;div&gt; 显示由父 css 类指定的源图像时遇到了此错误。 (2认同)

zay*_*uan 50

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

<Typography component={'span'} variant={'body2'}>
Run Code Online (Sandbox Code Playgroud)

根据排版文档:

component:用于根节点的组件.要么是使用DOM元素的字符串,要么是组件.默认情况下,它会将变体映射到良好的默认标题组件.

因此,排版选择<p>作为合理的默认值,您可以更改.可能带来副作用......对我有用.

  • 我使用了&lt;Typography component = {'div'}&gt;`,它现在可以在没有警告的情况下工作了。非常感谢您让我走上正轨! (2认同)

Ame*_*icA 17

我通过使用Material UI组件收到了这个警告,然后我测试component="div"了下面代码的as 道具,一切都变得正确了:

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

<Typography component="span">
  <Grid component="span">
    Lorem Ipsum
  </Grid>
</Typography>
Run Code Online (Sandbox Code Playgroud)

实际上,发生此警告是因为在 Material UI 中,Grid组件的默认 HTML 标签是divtag 而默认TypographyHTML 标签是ptag,所以现在发生了警告,

Warning: validateDOMnesting(...): <div> cannot appear as a descendant of <p>
Run Code Online (Sandbox Code Playgroud)

  • 不,亲爱的@EroStefano,开发人员有意遵循内联和块级别的层次结构规则。 (2认同)

Fed*_*Baù 15

带有材质用户界面!!!!

我花了相当多的时间,但感谢 Alex C 的这个答案 -->给出这个非常简单但聪明的解决方案

document.querySelectorAll(" p * div ")
Run Code Online (Sandbox Code Playgroud)

令我惊讶的是,Material UI DialogContentText组件DialogContentText API导致了这个问题

所以只是用来component={'span'}解决问题(不会影响风格)

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

Run Code Online (Sandbox Code Playgroud)


小智 12

您的组件可能呈现在另一个组件(例如<Typography> ... </Typography>)内。因此,它会将您的组件加载到<p> .. </p>其中,这是不允许的。

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

  • 我使用了&lt;Typography component = {'div'}&gt;`,它现在可以在没有警告的情况下工作了。非常感谢您让我走上正轨! (2认同)

jit*_*hu 12

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

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

不是有效的 HTML。根据规范中列出的标签省略规则,<p>标签会自动关闭<div>标签,从而使</p>标签没有匹配的<p>. 浏览器完全有权尝试通过<p>在 之后添加一个打开标记来纠正它<div>

<p></p><div></div><p></p>
Run Code Online (Sandbox Code Playgroud)

您无法将 a<div>放入 a<p>并从各种浏览器获得一致的结果。为浏览器提供有效的 HTML,它们会表现得更好。

你可以放在<div>里面,<div>所以如果你替换你<p><div class="p">并适当地设计它,你可以获得你想要的。


Vik*_*ikR 9

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

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>
  );
}
Run Code Online (Sandbox Code Playgroud)

像这样改变它会照顾它:

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>
    );
}
Run Code Online (Sandbox Code Playgroud)


小智 8

我通过使用<Card.Text>React 中组件的react-boostrap 部分得到了这个。我的组件都不在 p 标签中。<Card.Text> 默认情况下显示为

一旦呈现在 HTML 树中,并且基本上有一个自定义 React 组件在 a 中返回其 jsx 元素,<div> 它会导致 a<p><div>...</div></p>这是一个糟糕的 HTML。因此,要解决此问题,如果使用 <Card.Text>,您基本上可以使用“as”属性,如下所示, <Card.Text as='div'>这将解决警告,因为它允许一棵树,例如<div><div></div></div>


Ale*_*x C 7

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

  • 这是另一个版本,它使查找项目对我来说更加冗长 `document.querySelectorAll("p &gt; div")` (13认同)

小智 5

我有一个类似的问题,并将组件包装在“div”而不是“p”中,错误消失了。