<div> cannot appear as a descendant of <p> - javascript

I'm seeing this. It's not a mystery what it is complaining about:
Warning: validateDOMnesting(...): <div> cannot appear as a descendant of <p>. See ... SomeComponent > p > ... > SomeOtherComponent > ReactTooltip > div.
I'm the author of SomeComponent and SomeOtherComponent. But the latter is using an external dependency (ReactTooltip from react-tooltip). It's probably not essential that this is an external dependency, but it lets me try the argument here that it is "some code that's out of my control".
How worried should I be about this warning, given that the nested component is working just fine (seemingly)? And how would I go about changing this anyway (provided I don't want to re-implement an external dependency)? Is there maybe a better design that I'm yet unaware of?
For completeness sake, here's the implementation of SomeOtherComponent. It just renders this.props.value, and when hovered: a tooltip that says "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>
}
}
Thank you.

If this error occurs while using Material UI <Typography> https://material-ui.com/api/typography/, then you can easily change the <p> to a <span> by changing the value of the component attribute of the <Typography> element :
<Typography component={'span'} variant={'body2'}>
According to the typography docs:
component : The component used for the root node. Either a string to use a DOM element or a component. By default, it maps the variant to a good default headline component.
So Typography is picking <p> as a sensible default, which you can change. May come with side effects ... worked for me.

Based on the warning message, the component ReactTooltip renders an HTML that might look like this:
<p>
<div>...</div>
</p>
According to this document, a <p></p> tag can only contain inline elements. That means putting a <div></div> tag inside it should be improper, since the div tag is a block element. Improper nesting might cause glitches like rendering extra tags, which can affect your javascript and css.
If you want to get rid of this warning, you might want to customize the ReactTooltip component, or wait for the creator to fix this warning.

If you're looking for where this is happening, in console you can use: document.querySelectorAll(" p * div ")

I got this warning by using Material UI components, then I test the component="div" as prop to the below code and everything became correct:
import Grid from '#material-ui/core/Grid';
import Typography from '#material-ui/core/Typography';
<Typography component="span">
<Grid component="span">
Lorem Ipsum
</Grid>
</Typography>
Actually, this warning happens because in the Material UI the default HTML tag of Grid component is div tag and the default Typography HTML tag is p tag, So now the warning happens,
Warning: validateDOMnesting(...): <div> cannot appear as a descendant of <p>
Details (and some HTML theory regarding the warning) : The <div> cannot appear as a descendant of <p> message is shown due to the fact that the permitted content of a <p> tag is according to the standards set to the Phrasing Context which does not include <div> tags. See the links for more details.

Your component might be rendered inside another component (such as a <Typography> ... </Typography>). Therefore, it will load your component inside a <p> .. </p> which is not allowed.
Fix:
Remove <Typography>...</Typography> because this is only used for plain text inside a <p>...</p> or any other text element such as headings.

This is a constraint of browsers. You should use div or article or something like that in the render method of App because that way you can put whatever you like inside it. Paragraph tags are limited to only containing a limited set of tags (mostly tags for formatting text. You cannot have a div inside a paragraph
<p><div></div></p>
is not valid HTML. Per the tag omission rules listed in the spec, the <p> tag is automatically closed by the <div> tag, which leaves the </p> tag without a matching <p>. The browser is well within its rights to attempt to correct it by adding an open <p> tag after the <div>:
<p></p><div></div><p></p>
You can't put a <div> inside a <p> and get consistent results from various browsers. Provide the browsers with valid HTML and they will behave better.
You can put <div> inside a <div> though so if you replace your <p> with <div class="p"> and style it appropriately, you can get what you want.
Details (and some HTML theory regarding the warning) : The <div> cannot appear as a descendant of <p> message is shown due to the fact that the permitted content of a <p> tag is according to the standards set to the Phrasing Context which does not include <div> tags. See the links for more details.

The warning appears only because the demo code has:
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>
);
}
Changing it like this takes care of it:
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>
);
}

I got this from using a react-boostrap <Card.Text> section of a component in React. None of my components were in p tags. <Card.Text> by default shows up as a in the HTML tree once rendered and basically having a custom React component returning its jsx elements within a <div> it causes a <p><div>...</div></p> which is a bad HTML. So to fix this issue if one is using <Card.Text> you can basically use the 'as' attribute as the following
<Card.Text as='div'> and this will resolve the warning because it allow a tree such as <div><div></div></div>

With Material UI !!!!!
I've spent an embarassing amount of time but thanks to this answer --> here by Alex C which gave this very simple yet smart solution
document.querySelectorAll(" p * div ")
So at my surprise , was the Material UI DialogContentText component DialogContentText API that caused the issue
So just use component={'span'} to fix the problem (it won't effect the style)
<DialogContentText id="alert-dialog-inputs" component={'span'}/>

I had a similar issue and wrapped the component in "div" instead of "p" and the error went away.

I got this from using a custom component inside a <Card.Text> section of a <Card> component in React. None of my components were in p tags

If you are using ReactTooltip, to make the warning disappear, you can now add a wrapper prop with a value of span, like this:
<ReactTooltip wrapper="span" />
Since the span is an inline element, it should no longer complain.

There is a problem in App.js during its rendering.
Don't use <div>...</div> to render just use <>...</>.

I had same issue with react-bootstrap and with Alex C's solution i found that i use <div> in <Card.Text> which is kinda <p>
<Card.Text>
<div>{name}</div>
<div>{address}</div>
<div>{size}</div>
</Card.Text>

I got this error when using Chakra UI in React when doing inline styling for some text. The correct way to do the inline styling was using the span element, as others also said for other styling frameworks. The correct code:
<Text as="span" fontWeight="bold">
Bold text
<Text display="inline" fontWeight="normal">normal inline text</Text>
</Text>

If you couldn't solve problem use bottom method
You have this problem because, you Open Grid tag or div in text tag and It can be false.
For example I write part of the code That have problem.look at it:
<Typography>
text
<Grid>
</Grid>
</Typography>
Be careful I open Grid tag in Typography tag. So It is false if we Open Grid tag in typography tag.
As far as my knowledge know when We open in typograghy tag, We are Deviating from the MUI standard.
So for best way you can us this Code:
<Grid>
<Typography>
text
</Typography>
</Grid>
If you used this code, you would not Any problem.
As result if you have problem again
You have to check components and
See in which component you did not Choose the correct mode.
You should check:
Span typography h1 h2 h3 h4 h5 h6 p
I hope I helped you .

I resolved that issue by removing my tag that I used to wrap around my 2 textfields that were causing that same error log.

You can not descendant of ;
Error: <p><div>aaaa</div></p>
Solution <div><p>aaaa</p></div>

(Extra)
Problem can be <p> elements inside <p> element in other similar errors.
Error:
<p>
<p>
</p>
</p>

Related

React textarea loses focus unexpectedly

I've created a Row and a Col components for an Card in Accordion using Bootstrap - simple, not React.Bootstrap or whatever. Row and Col just show their children, the Card just has more props and also just shows the children. Like that:
class Col extends React.Component {render () {return (
<div className='col' id={'col_'+this.props.colid} key={shortid.generate()}>
{this.props.children}
</div>)}}
class Row extends React.Component {render () { return (
<div className='row' id={'row_'+this.props.rowid} key={shortid.generate()}>
{this.props.children}
</div>)}}
Then I want to insert a textarea, which is provided with a function to make some changes to the text and I display these changes within a div below the textarea. Also I've got a button, that copies the text to buffer, based on clipboard.js
The first version of render function works just fine, but it doesn't give me the needed design, so I came up with the second version, based on Row and Col components, described above.
The contents mainly does not differ - the same textarea, checkbox, button and div. What differs is the layout. In the first version there is no layout at all, in the second I tried my best :)
So:
render () { return (<React.Fragment>
<textarea id='xng0' onChange={this.handleChange} ref={this.xng0ref} />
<CopyButton target="st0" message="Copy text" /> <br />
<input type='checkbox' onChange={this.toggleTranslit}
defaultChecked={this.state.tranParam} /><span>Translit?</span><br />
<div id='st0' border='1' ref={this.st0ref} >
{this.state.st0value}
</div></React.Fragment>)}
The second version:
render () {return ( <React.Fragment><Row><Col>
<textarea id='xng0' onChange={this.handleChange} ref={this.xng0ref} />
</Col><Col><Row><Col>
<CopyButton target="st0" message="Copy text" />
</Col></Row>
<Row><Col>
<input type='checkbox' onChange={this.toggleTranslit}
defaultChecked={this.state.tranParam}
/><span>Translit?</span>
</Col></Row>
</Col>
</Row>
<Row>
<div id='st0' border='1' ref={this.st0ref}>
{this.state.st0value}
</div></Row></React.Fragment>)}
My problem is: while the first render() version keeps focus in the textarea, when I type, the second version throws the focus off the textarea after the first letter was typed AND clears the textarea. That is I have no possibility to input some long text - I get only one letter.
What did I miss? Why this happens and how to make the focus stable?
As you were already prompted in the comments, you have unique keys for each render on the Col and Row components, because key={shortid.generate()}.
After writing a character in the textarea, you most likely change the state, then rerender happens and in the place of the current textarea, a new one appears, naturally without focus.
I recommend that you carefully read why the keys are created in the React. Link https://reactjs.org/docs/lists-and-keys.html#keys.
I must say right away that they were created to identify the list items, which is completely violated when you generate unique keys on each render.
please add 'value' property to your textarea

Can I add another component inside a semantic-ui-react card without it breaking?

Background
I have an app that displays tv programs in semantic cards. There are six cards per row. I would like to add a comment container on each card. The comment container will eventually list comments specific to each program.
Since my return needs to include two JSX components, I must wrap them in a div. However, doing that messes up my formatting for six cards per row. I am unsure of a workaround, except possibly overwriting with my own CSS somehow. Google hasn't been much help, though maybe I am just not using the correct search terms.
Any ideas on what I should do?
Code
Programs.js
Link to full file
return(
<div>
<Grid columns='six' divided='vertically'>
<Grid.Row >
{props.programs && props.programs.map((program) => <Program key={program.name} program={program} />)}
</Grid.Row>
</Grid>
</div>
)
Program.js. I want my to go after the
Link to full file
return(
<Grid.Column>
<Card onClick={(_) => {}}>
<Image src={program ? program.image : null} wrapped ui={false} />
<Card.Content>
<Card.Header>{program ? program.name: null}</Card.Header>
<Card.Meta>
<span className='date'>{program ? program.network : null}</span>
</Card.Meta>
</Card.Content>
</Card>
</Grid.Column>
)
Thank you very much for your time!
According to the docs from Semantic UI React, it's fine as long as you keep everything in containers called content and context extra.
See also their example (they show code) showing "blocks of content" in https://react.semantic-ui.com/views/card/#content-content-block

React component closing tag

I'm new to React and I'm trying to figure out the purpose/use of <MyComponent></MyComponent> vs <MyComponent />. I can't seem to find information on anything except self-closing tags.
I've created a basic tab scroller as a JSFiddle using the self-closing <MyComponent /> and subsequent props, and I'm wondering if there's a better way to write in React than what I've done.
class TabScroller extends React.Component {
render() {
return (
<div className="tabScroller">
<div className="NavList">
<TabNav handleClick={this.handleNavClick} />
<TabList
tabs={this.state.tabs}
activeTab={this.state.activeTab}
scrollPosition={this.state.scrollPosition}
handleClick={this.handleTabClick}
/>
</div>
<TabContent content={this.state.tabs[this.state.activeTab].content} />
</div>
);
}
}
// ========================================
ReactDOM.render(
<TabScroller />,
document.getElementById('root')
);
In React's JSX, you only need to write <MyComponent></MyComponent> when the component has child components, like this:
<MyComponent>
<Child />
<Child />
<Child />
</MyComponent>
If there is nothing between <MyComponent> and </MyComponent>, then you can write it either <MyComponent/> or <MyComponent></MyComponent> (but <MyComponent/> is generally preferred). Details in Introducing JSX.
Just as a side note, you'd access those children in your component via the special props.children property. More in JSX in Depth: Children in JSX.
Note that this is very much not like HTML or XHTML. It's its own (similar) thing with different rules. For instance, in HTML, <div/> is exactly the same thing as <div>: A start tag, for which you must eventually have an end tag. Not so JSX (or XHTML). The rules for HTML are that void elements (elements that never have markup content, such as br or img) can be written with or without / before > and they never get an ending tag, but non-void elements (like div) must always have an ending tag (</div>), they cannot be self-closing. In JSX (and XHTML), they can be.
The purpose of self-closing tags is simply the fact that it is more compact. This is especially useful when said component doesn't have any children that you typically wrap around a parent.
So usually for leaf components (i.e compoents that do not have any children), you use the self-closing syntax. Like: <Component />. And even if it has props, you can do: <Component foo="bar" />.
However, remember that children is a prop, so you could technically do:
<Component children={<span>foo</span>} />
but I find it less readable and advise against it (read disclaimer below).
To summarize, these are equivalent:
<Component /> = <Component></Component>
<Component foo="bar" /> = <Component foo="bar"></Component>
<Component children={<span>foo</span>}></Component> =
<Component><span>foo</span></Component>
You can use whichever approach you prefer. Though praxis is to use the short-hand version when there are no children.
Disclaimer: While defining childen prop by its object key value will technically work, doing so is strongly discouraged as it disrupts the API as it is meant to be used. Use this version only if confident in what you are doing.

How to show a component and a variable within the true case in a ternary in React/jsx?

I want to do a ternary inside of a div that renders a component I’ve built and a variable vs. a button, but my syntax is throwing an error. Does anyone know how I can alter this so that it does what I want?
<div>
{thing ? <WorkListBadge /> item.resource : <button> Click Me
</button> }
</div>
It’s erroring on the <WorkListBadge /> part with
Module build failed: SyntaxError: Unexpected token, expected :
I tried a bunch of different jsx variations with no luck. This is within a jsx file.
I'm new to React and could totally be going about this the wrong way as well. Thanks in advance!
You can only render a single entity in a ternary. Wrap both of your elements in a <div> to combine them into a single item. Remember to add curly braces for item.resource
<div>
{thing ? <div><WorkListBadge /> {item.resource}</div> : <button> Click Me
</button> }
</div>

Polymer content issue for ie11

I am using polymer 1.
I have used something like this in polymer and I am passing the section's content from the point where i use this component.
It's working fine for chrome and firefox.
But for IE-11, I am not getting anything for the content.
<section id="asdf" class="className">
<content select="section"></content>
</section>
Does someone know the about this issue ?
Try setting the select attribute value to contain a period. The select attribute needs a selector not a string.
<template>
<header>Local dom header followed by distributed dom.</header>
<content select=".content"></content>
<footer>Footer after distributed dom.</footer>
</template>
Polymer docs

Categories