Warning: validateDOMNesting(...): <div> cannot appear as a descendant of <p> - css

I know the what the problem is. But I can't find out a solution. a paragraph cannot contain any other tags. But in my case ,I didn't use any paragraph tags.
return (
<div className={classes.root}>
<Stepper activeStep={activeStep} alternativeLabel>
{steps.map(label => {
return (
<Step key={label}>
<StepLabel>{label}</StepLabel>
</Step>
);
})}
</Stepper>
<div>
{this.state.activeStep === steps.length ? (
<div>
<div>All steps completed</div>
<Button onClick={this.handleReset}>Reset</Button>
</div>
) : (
<div>
<div>{getStepContent(activeStep)}</div>
<div>
<Button
disabled={activeStep === 0}
onClick={this.handleBack}
className={classes.backButton}
>
Back
</Button>
<Button variant="contained" color="primary" onClick={this.handleNext}>
{activeStep === steps.length - 1 ? 'Finish' : 'Next'}
</Button>
</div>
</div>
)}
</div>
</div>
);
}
}
My getStep method .. it looks like returning a paragraph. But it should return a component of react..
function getStepContent(stepIndex) {
switch (stepIndex) {
case 0:
return <FormPart1 setFormPart1Value={getValueFormPart1.bind(this)} className={{
alignContent:'center'
}
} />;
case 1:
return <FormPart2 />;
case 2:
return <PerformanceTable />;
case 3:
return <WorkHabitTable />;
case 4:
return <OtherDetails />;
case 5:
return <PerformanceOverall />;
default:
return 'Uknown stepIndex';
}
This code is taken from Material-UI directly. So anyone suggests me a solution to get rid of the wrong appearing in the browser.

The warning message states that you cannot use div tag inside the p tag like:
<p>
<div>some text</div>
</p>
This is invalid html. The p tag can contain inline elements not block level elements.
So, one of your component is using such. You need to fix that. (Simply replace p tag with div tag)
Or, the library itself might have used such? You may fix by your own or wait for the fixes by submitting an issue.

You can always wrap your Material-UI Button in <ButtonGroup>.
It helped in my case.
<ButtonGroup
orientation="vertical"
color="primary"
aria-label="vertical outlined primary button group"
>
<Button>One</Button>
<Button>Two</Button>
<Button>Three</Button>
</ButtonGroup>

Related

How do I add styles to a component that is passed as prop in React?

I have a component that is passed as a label prop. I need to add width: 100% for it because otherwise, I cannot use justify-content: space between for my div. Here is how it looks like in developer tools.
return (
<div className={classes.row}>
<Checkbox
value={deviceId}
className={classes.checkbox}
checked={Boolean(selected)}
onChange={handleToggle}
label={
<div>
<Tooltip title={t('integrations.deviceEUI')} placement={'top-start'}>
<Typography variant="body1" className={classes.item}>
{deviceEui}
</Typography>
</Tooltip>
<Tooltip title={t('integrations.deviceName')} placement={'top-start'}>
<Typography variant="body1" className={classes.item}>
{name || ''}
</Typography>
</Tooltip>
</div>
}
/>
</div>
);
};
I'm not sure I fully understand the issue, but if you want to simply add styles to a React component, you can simply do the following:
cont labelStyle = {
width: '100%'
};
Then inside your return statement, you could attach this labelStyle to the parent <div> like so:
<div style={labelStyle}>
//other components
</div>
If this isn't what you really mean, then please consider outlining the issue a little more clearly, thanks!
In React Native version of this problem, you can simply give the "style" prop to the component as:
const NewComponent = ({style}) => {}
and now you are able to reach to the "style" prop from another file.
Now, "style" prop is available to use in "NewComponent", write the following code:
<NewComponent style={{}}/>

Purple lines / Conditionnal rendering

I have those purple lines ( as my screen bellow ).
I doing some conditionnal rendering, I'd like to know if I can remove all those purple lines.
I've heard removing all divs and adding React.Fragments might help, this what I've done so far. But the issue is still there.
If anyone could tell where the issue might come from, I'd be grateful !
the main view / Render 1
<div className="user-infos">
<h4><u> Parameters </u></h4>
{ (componentState == "edit") ?
<form >
<Render 3/>
</form>
: (componentState == "index") ?
<Render 2/>
: (componentState == "delete") ?
<React.Fragment>
<p> Are you sure you want to leave us ? </p>
<p> If yes, you have to type your email and press "confirm".</p>
<form>
<input type="text" />
<input type="submit" value="confirm email"/>
</form>
<span>
<button> Delete ur account</button>
<button> Cancel </button>
</span>
</React.Fragment>
: ""
}
</div>
Render 2
return (
<React.Fragment>
<p> Username : John </p>
<p> Timezone : London </p>
<span>
<button> Edit Profile </button>
<button> Delete account </<button>>
</span>
</React.Fragment>
Render 3
return (
<React.Fragment>
<label for="email"> Username :
<input type="text"/>
</label>
<label for="text"> Timezone :
<span>
<select
onChange={options}
<options>
</select>
</span>
</label>
<button type="submit"> Save Profile </button>
<button> Cancel </button>
</React.Fragment>
);
By default, chrome adds styling to your html. In the case of <p>, it adds the following css to your element.
If you want the margin to disappear, you need to set margin: 0; on your <p> element to overwrite chrome's styling.
The purple dash line occurs when there is available space for the elements to expand into. See here. From what I can tell from comparing flexboxes with other display types, the purple dash with purple background is specifically for space inside flexboxes (display:flex in CSS).
Would need to see your CSS to be sure, but I imagine there's justify-content: space-between telling the flexbox to evenly distribute the remaining empty space between the elements as well as flex-direction: column telling the flexbox to stack the child elements vertically.
If that's the case, you can remove justify-content: space-between and use flexbox styling to change things to how you want it to look. I found this website helpful: A Complete Guide to Flexbox

CSS transition doesn't work with react-portal

I am using react-portal to make a dialog and added transition, it went well as
// App.js
return (
<div className="App">
<button onClick={() => setIsOpen(true)}>Click to see dialog</button>
<PortalDialog isOpen={isOpen} setIsOpen={setIsOpen}>
This is content of dialog
</PortalDialog>
{/* animation works */}
</div>
)
//PortalDialog.js
return (
<Portal>
<DialogWrapper className={`${isOpen ? "active" : ""}`}>
{children}
<button onClick={() => setIsOpen(false)}>Close</button>
</DialogWrapper>
</Portal>
);
until I noticed PortalDialog is created every time on render which I don't want so I added a condition
<div className="App">
<button onClick={() => setIsOpen(true)}>Click to see dialog</button>
{isOpen && (
<PortalDialog isOpen={isOpen} setIsOpen={setIsOpen}>
This is content of dialog
</PortalDialog> // animation doesn't work
)}
</div>
Now it's not rendered everytime but CSS transition doesn't work anymore and I think that's because of the condition I added. But I couldn't find a way to add transition with react-portal, what do I need to do here ? I made a codesandbox example here.
Looks like ReactTransitionGroup is the answer, I wrapped my PortalDialog component with CSSTransition component as shown in their codesandbox sample.
<CSSTransition
in={isOpen}
timeout={300}
classNames="dialog"
unmountOnExit
>
<Portal>
<DialogWrapper>
{children}
<button onClick={() => setIsOpen(false)}>Close</button>
</DialogWrapper>
</Portal>
</CSSTransition>
Transition is now working without being created on every render.

Adding a required in a basic for of an input and button

I tried to add a required element (when the box become red if not text is inside) on my form but without success, I installed react-strap, Bootstrap. when I apply many changed it didn't work for no reason
and it's just not moving if someone know why I would be happy.
render() {
return (
<div>
<form class="needs-validation" novalidate>
<InputGroup size="sm">
<InputGroupAddon addonType="append" className="m-2">
<Input
className="form-control"
placeholder="Add a new To-Do. "
onChange={(e) => this.updateInput(e.target.value)}
value={this.state.input}
onKeyPress={this.handleKeyPress}
required
/>
<Button
color="primary"
size="sm"
className="add-todo"
onClick={this.handleAddTodo}
>
Add
</Button>
</InputGroupAddon>
</InputGroup>
</form>
</div>
);
}
export default connect(null, { addTodo })(AddTodo);
// export default AddTodo;
What you are doing is passing required as a prop to your class Input. You need to add the html tag when the field renders, i.e. in Input.js:
return (
<input ... required={this.props.required}>
)
i think you should add the 'is-invalid' class to the input element if that field is empty.
https://getbootstrap.com/docs/4.0/components/forms/?#server-side

How to display a list of items from a reactjs map loop horizontally with wrap?

I have a list of items (dynamically created buttons) coming from a reactjs map function. I want them listed horizontally and also allow wrapping remaining items to the next line if needed. Can some one please help with this. Given below is my code snippet.
return( <div>
{ relevantMessages.map(function(thisQuestion){
return
<p key={thisQuestion.id}>
<button key={thisQuestion.id} onClick={() => this.sendThisMessage(thisQuestion.question)}>
{thisQuestion.title}
</button>
</p>
}, this)
}
</div>)
You can use css to align horizontally.
For example:
return( <div>
{ relevantMessages.map(function(thisQuestion){
return
<p key={thisQuestion.id} style="display:inline-block;">
<button key={thisQuestion.id} onClick={() => this.sendThisMessage(thisQuestion.question)}>
{thisQuestion.title}
</button>
</p>
}, this)
}
</div>)
Using span tag instead of p tag in the above code snippet solved my issue.
This isn't really an issue with React, but more so with CSS.
What you are probably looking for is something such as flex-box. Check out css-tricks for a good tutorial on how to use it.
Or try flexbox-froggy for a gamified of learning it :)

Resources