Reputation: 1382
I have a project and in this project I have several interfaces, and among these interfaces I have a login interface, the login interface is working, but I have this error in the console:
validateDOMNesting(...): <div> cannot appear as a descendant of <p>.
What caused it and how can I solve it?
And this is the component from which it became clear to me that the ERROR appeared
import Card from "@material-ui/core/Card";
import CardContent from "@material-ui/core/CardContent";
import { makeStyles } from "@material-ui/core/styles";
import { darken } from "@material-ui/core/styles/colorManipulator";
import Tab from "@material-ui/core/Tab";
import Tabs from "@material-ui/core/Tabs";
import Typography from "@material-ui/core/Typography";
import clsx from "clsx";
import { motion } from "framer-motion";
import { useState } from "react";
import { Link } from "react-router-dom";
import JWTLoginTab from "./tabs/JWTLoginTab";
const useStyles = makeStyles((theme) => ({
root: {
background: `linear-gradient(to right, ${
theme.palette.primary.dark
} 0%, ${darken(theme.palette.primary.dark, 0.5)} 100%)`,
color: theme.palette.primary.contrastText,
},
leftSection: {},
rightSection: {
background: `linear-gradient(to right, ${
theme.palette.primary.dark
} 0%, ${darken(theme.palette.primary.dark, 0.5)} 100%)`,
color: theme.palette.primary.contrastText,
},
}));
function Login() {
const classes = useStyles();
const [selectedTab, setSelectedTab] = useState(0);
function handleTabChange(event, value) {
setSelectedTab(value);
}
return (
<div
className={clsx(
classes.root,
"flex flex-col flex-auto items-center justify-center flex-shrink-0 p-16 md:p-24"
)}
>
<motion.div
initial={{ opacity: 0, scale: 0.6 }}
animate={{ opacity: 1, scale: 1 }}
className="flex w-full max-w-400 md:max-w-3xl rounded-20 shadow-2xl overflow-hidden"
>
<Card
className={clsx(
classes.leftSection,
"flex flex-col w-full max-w-sm items-center justify-center shadow-0"
)}
square
>
<CardContent className="flex flex-col w-full py-96 max-w-320">
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1, transition: { delay: 0.2 } }}
>
<div className="flex items-center mb-6">
<div
// justifyContent="flex-start"
// alignItems="flex-start"
className="flex mb-32"
>
<div>
<Typography
className="text-20 font-semibold logo-text"
color="inherit"
>
Login
</Typography>
<Typography
className="text-14 tracking-widest -mt-13 font-700 mb-10"
color="textSecondary"
>
fill in your login information
</Typography>
</div>
</div>
</div>
</motion.div>
<JWTLoginTab />
</CardContent>
<div className="flex flex-col items-center justify-center pb-32">
<div>
<span className="font-normal mr-8">Don't have an account?</span>
<Link className="font-normal" to="/register">
Register
</Link>
</div>
<Link className="font-normal mt-8" to="/">
Back to Dashboard
</Link>
</div>
</Card>
<div
className={clsx(
classes.rightSection,
"hidden md:flex flex-1 items-center justify-center p-64"
)}
>
<div className="max-w-320">
<motion.div
initial={{ opacity: 0, y: 70 }}
animate={{ opacity: 1, y: 0, transition: { delay: 0.2 } }}
>
<img
src="assets/images/logos/brick.png"
color="#F6F7F9"
width="110rem"
height="100rem"
/>
</motion.div>
</div>
</div>
</motion.div>
</div>
);
}
export default Login;
jwtLoginTab.js:
import { yupResolver } from "@hookform/resolvers/yup";
import TextField from "@material-ui/core/TextField";
import Button from "@material-ui/core/Button";
import Icon from "@material-ui/core/Icon";
import IconButton from "@material-ui/core/IconButton";
import InputAdornment from "@material-ui/core/InputAdornment";
import { useEffect, useState } from "react";
import { Controller, useForm } from "react-hook-form";
import { useDispatch, useSelector } from "react-redux";
import { submitLogin } from "app/auth/store/loginSlice";
import * as yup from "yup";
import _ from "@lodash";
/**
* Form Validation Schema
*/
const schema = yup.object().shape({
email: yup
.string()
.email("You must enter a valid email")
.required("You must enter an email"),
password: yup
.string()
.required("Please enter your password.")
.min(4, "Password is too short - should be 4 chars minimum."),
});
const defaultValues = {
email: "",
password: "",
};
function JWTLoginTab(props) {
const dispatch = useDispatch();
const login = useSelector(({ auth }) => auth.login);
const {
control,
setValue,
formState,
handleSubmit,
reset,
trigger,
setError,
} = useForm({
mode: "onChange",
defaultValues,
resolver: yupResolver(schema),
});
const { isValid, dirtyFields, errors } = formState;
const [showPassword, setShowPassword] = useState(false);
useEffect(() => {
setValue("email", "[email protected]", {
shouldDirty: true,
shouldValidate: true,
});
setValue("password", "ria@123", {
shouldDirty: true,
shouldValidate: true,
});
}, [reset, setValue, trigger]);
useEffect(() => {
login?.errors?.forEach((error) => {
setError(error.type, {
type: "manual",
message: error.message,
});
});
}, [login.errors, setError]);
function onSubmit(model) {
dispatch(submitLogin(model));
console.log("2-JWTLoginTab: ", model);
}
return (
<div className="w-full">
<form
className="flex flex-col justify-center w-full"
onSubmit={handleSubmit(onSubmit)}
>
<Controller
name="email"
control={control}
render={({ field }) => (
<TextField
{...field}
className="mb-16"
type="text"
error={!!errors.email}
helperText={errors?.email?.message}
label="Email"
InputProps={{
endAdornment: (
<InputAdornment position="end">
<Icon className="text-20" color="action">
user
</Icon>
</InputAdornment>
),
}}
variant="outlined"
/>
)}
/>
<Controller
name="password"
control={control}
render={({ field }) => (
<TextField
{...field}
className="mb-16"
label="Password"
type="password"
error={!!errors.password}
helperText={errors?.password?.message}
variant="outlined"
InputProps={{
className: "pr-2",
type: showPassword ? "text" : "password",
endAdornment: (
<InputAdornment position="end">
<IconButton onClick={() => setShowPassword(!showPassword)}>
<Icon className="text-20" color="action">
{showPassword ? "visibility" : "visibility_off"}
</Icon>
</IconButton>
</InputAdornment>
),
}}
required
/>
)}
/>
<Button
type="submit"
variant="contained"
color="primary"
className="w-full mx-auto mt-16"
aria-label="LOG IN"
disabled={_.isEmpty(dirtyFields) || !isValid}
value="legacy"
>
Login
</Button>
</form>
</div>
);
}
export default JWTLoginTab;
Upvotes: 0
Views: 1565
Reputation: 426
You could tell Typography to be rendered as span
like so:
<Typography component="span">Your Text</Typography>
Upvotes: 1
Reputation: 333
React render each component you are calling to your screen as a <div>
element. If peradventure, you called a component inside the <p>
tag element, this error will occur. This simply means you are rendering a <div>
inside <p>
tag. This happens to external modules too,@materialui, @react-bootstrap, and many other modules.
In a visual sense,
<p><div></div></p>
Upvotes: 1