Last updated: Apr 7, 2024
Reading time·4 min
The React.js "Warning: validateDOMNesting(...): div cannot appear as a
descendant of p" occurs when you try to nest a div
tag inside a p
tag,
either directly or when using components from a third-party library.
To resolve the issue, use a span inside of the p
tag or wrap the p
tag in
a div
element.
Warning: validateDOMNesting(...): <div> cannot appear as a descendant of <p>. at div at p at div at App
Here is an example of how the warning is caused.
export default function App() { return ( <> {/* ⛔️ This causes the warning */} <p> <div>bobbyhadz.com</div> </p> </> ); }
Notice that the div
element is wrapped in a p
tag. This is not allowed
because a div
element cannot be a descendant of a p
element.
A <p>
tag can only contain inline elements (such as span
), so putting a
block-level element such as a <div>
inside a p
tag is not valid.
If you got the warning directly in your code (and not when using a third-party library), you have 2 options:
p
tag in a div
element instead.// ✅ No warning export default function App() { return ( <> <div> <p>bobbyhadz.com</p> </div> </> ); }
We switched the div
and p
elements, so now the paragraph is a descendant of
the div and the warning is no longer shown.
span
element instead of a div
in the p
tag.// ✅ No warning export default function App() { return ( <> <p> <span>bobbyhadz.com</span> </p> </> ); }
Using a span
element as a descendant of a p
tag is valid and span
elements
are often used to style specific parts of a paragraph.
You can also nest multiple div
tags.
// ✅ No warning <div> <div>bobbyhadz.com</div> </div>
Similarly, a p
element cannot be a descendant of another p
element (can't
nest p
tags) because they are block-level elements.
// ⛔️ Warning: validateDOMNesting(...): <p> cannot appear as a descendant of <p>. <p> <p>bobbyhadz.com</p> </p>
However, a span
element can be a descendant of a p
element.
// ✅ Valid code (no warnings) <p> <span>bobbyhadz.com</span> </p>
The warning is also shown when you use components from a third-party library, e.g. material UI.
Here is an example of how the error occurs when using custom components from the Material UI library.
import {Typography, Grid} from '@mui/material'; export default function App() { return ( <> {/* ⛔️ Warning: validateDOMNesting(...): <div> cannot appear as a descendant of <p>. */} <Typography> bobby hadz com <Grid>one</Grid> two three </Typography> </> ); }
You can right-click on an element and click inspect to see the underlying DOM nodes.
Here is the DOM layout in the Elements tab of my browser.
As the image shows we are trying to nest a div
element (Grid
) inside a p
element (Typography
).
In this case, you can use the component
prop to set the DOM note of the
Typography
component.
// ✅ no Warnings caused (div > div) import {Typography, Grid} from '@mui/material'; export default function App() { return ( <> <Typography component='div'> bobby hadz com <Grid>one</Grid> two three </Typography> </> ); }
I set the component
prop on the Typography
element to div
, so now we have
a div
that is a descendant of another div
which is perfectly valid.
The issue can also be resolved if we set the component
prop to span
.
// ✅ no Warnings caused (span > div) import {Typography, Grid} from '@mui/material'; export default function App() { return ( <> <Typography component="span"> bobby hadz com <Grid>one</Grid> two three </Typography> </> ); }
A div
element can be a descendant of a span
, so the issue is resolved.
The component
prop can be set on many different Material UI custom components.
Here is an example that sets the prop when using the DialogContentText
component.
import {DialogContentText} from '@mui/material'; export default function App() { return ( <> <DialogContentText component="span"> bobbyhadz.com </DialogContentText> </> ); }
The prop sets the component that is used for the root DOM node.
If you need to apply a theme typography style, set the variant
prop as well
(e.g. body2
, h2
, h3
, etc).
import {Typography, Grid} from '@mui/material'; export default function App() { return ( <> <Typography component="span" variant="body2"> bobby hadz com <Grid>one</Grid> two three </Typography> </> ); }
You can view the available values for the variant
prop in
this table in the docs.
By default, a Grid
component is a div
and a Typography
component is a p
element, so we have to be mindful of the DOM structure even when using
third-party components.
If you use other third-party libraries that cause the issue, you have to check the props the custom components take.
The component most likely takes a prop that you can pass to set the type of the underlying DOM node.
Most commonly the warning is shown when you try to:
div
as a descendant of a p
elementp
as a descendant of a p
elementIf you aren't able to identify which element caused the issue:
F12
.document.querySelectorAll("p > div")
The line prints the div
elements that are direct descendants of a p
element.
If you don't get any matches, use the following line instead.
document.querySelectorAll(" p * div ")