3

I have a react app where I am using MUI. Its having two pages lets say Login & Signup. And both these pages were wrapped by a toplevel code:

function TabPanel(props) {
    const { children, value, index, ...other } = props;

    return (
      <div
        role="tabpanelswitch"
        hidden={value !== index}
        id={`tabpanel-${index}`}
        aria-labelledby={`tab-${index}`}
        {...other}
      >
        {value === index && (
          <Box>
            <Typography>{children}</Typography>
          </Box>
        )}
      </div>
    );
  }

return (
    <Grid
      container
      component="div"
      marginTop="10px"
      direction="row"
      alignItems="center"
    >
      <Paper style={paperStyle} elevation={10}>
        <Tabs
          value={value}
          onChange={handleChange}
          aria-label="disabled tabs example"
          TabIndicatorProps={{
            style: {
              backgroundColor: "#xxxxxxxx",
            },
          }}
          centered
        >
          <Tab label="Sign In" />
          <Tab label="Sign Up" />
        </Tabs>
        <TabPanel value={value} index={0}>
          <Login handleChange={handleChange} />
        </TabPanel>
        <TabPanel value={value} index={1}>
          <Signup />
        </TabPanel>
      </Paper>
    </Grid>
  );
};

SignIn | SignUp

After clicking the Login button, I am getting the above two pages for login/signup. But When clicking the login button, I am getting the following warning in the browser's console though no impact on the functionality:

react-dom.development.js:86 
        
    Warning: validateDOMNesting(...): <p> cannot appear as a descendant of <p>.
    at p
    at http://localhost:3000/static/js/bundle.js:6140:66
    at Typography (http://localhost:3000/static/js/bundle.js:46766:87)
    at div
    at http://localhost:3000/static/js/bundle.js:6140:66
    at Toolbar (http://localhost:3000/static/js/bundle.js:45655:82)
    at header
    at http://localhost:3000/static/js/bundle.js:6140:66
    at Paper (http://localhost:3000/static/js/bundle.js:40510:82)
    at http://localhost:3000/static/js/bundle.js:6140:66
    at AppBar (http://localhost:3000/static/js/bundle.js:25701:83)
    at div
    at http://localhost:3000/static/js/bundle.js:6140:66
    at Grid (http://localhost:3000/static/js/bundle.js:33861:87)
    at Login (http://localhost:3000/static/js/bundle.js:3249:5)
    at p
    at http://localhost:3000/static/js/bundle.js:6140:66
    at Typography (http://localhost:3000/static/js/bundle.js:46766:87)
    at div
    at http://localhost:3000/static/js/bundle.js:6140:66
    at Box (http://localhost:3000/static/js/bundle.js:50403:72)
    at div
    at TabPanel (http://localhost:3000/static/js/bundle.js:311:7)
    at div
    at http://localhost:3000/static/js/bundle.js:6140:66
    at Paper (http://localhost:3000/static/js/bundle.js:40510:82)
    at div
    at http://localhost:3000/static/js/bundle.js:6140:66
    at Grid (http://localhost:3000/static/js/bundle.js:33861:87)
    at SignInOutContainer (http://localhost:3000/static/js/bundle.js:348:74)
    at Routes (http://localhost:3000/static/js/bundle.js:108594:5)
    at Router (http://localhost:3000/static/js/bundle.js:108527:15)
    at BrowserRouter (http://localhost:3000/static/js/bundle.js:107336:5)
    at App (http://localhost:3000/static/js/bundle.js:73:56)
    at AuthContextProvider (http://localhost:3000/static/js/bundle.js:5226:5)
printWarning @ react-dom.development.js:86
error @ react-dom.development.js:60
validateDOMNesting @ react-dom.development.js:10849
createInstance @ react-dom.development.js:10930
completeWork @ react-dom.development.js:22187
completeUnitOfWork @ react-dom.development.js:26596
performUnitOfWork @ react-dom.development.js:26568
workLoopSync @ react-dom.development.js:26466
renderRootSync @ react-dom.development.js:26434
performConcurrentWorkOnRoot @ react-dom.development.js:25738
workLoop @ scheduler.development.js:266
flushWork @ scheduler.development.js:239
performWorkUntilDeadline @ scheduler.development.js:533

Similarly, total 5 warnings visible at different sections of the code. I tried defining the span via components but still no improvement:

react-dom.development.js:86   
Warning: validateDOMNesting(...): <p> cannot appear as a descendant of <p>.        
Warning: validateDOMNesting(...): <div> cannot appear as a descendant of <p>.
Warning: validateDOMNesting(...): <header> cannot appear as a descendant of <p>.    
Warning: validateDOMNesting(...): <h2> cannot appear as a descendant of <p>.
Warning: validateDOMNesting(...): <form> cannot appear as a descendant of <p>.
  • The login code is something like this:

  return (
    <Grid container direction="row" alignItems="center">
      <AppBar color="inherit" position="fixed">
        <Toolbar>
          <NavLink to="/" style={{ textDecoration: "none" }}>
            <Box
              component="img"
              src={devicon}
              width="30px"
              height="30px"
              paddingRight={1}
              paddingTop={0.8}
            />
          </NavLink>
          <Typography
            color="green"
            flexGrow={1}
            fontWeight="bold"
            display="flex"
            sx={{
              alignSelf: "center",
              fontSize: { xs: "1.125rem", sm: "2.125rem" },
            }}
          >
            devplatform
          </Typography>
          <Stack spacing={1} direction="row">
            <Button
              variant="outlined"
              color="success"
              size="small"
              href="/login"
            >
              Login
            </Button>
            <Button
              variant="contained"
              color="success"
              size="small"
              href="/signup"
            >
              Sign Up
            </Button>
          </Stack>
        </Toolbar>
      </AppBar>
      <Grid
        container
        component="span"
        direction="row"
        alignItems="center"
      >
        <Paper style={paperStyle}>
          <Grid align="center">
            <Avatar style={avatarStyle}>
              <LockOutlinedIcon />
            </Avatar>
            <h2 style={headerStyle}>Member Login</h2>
          </Grid>
          <Formik initialValues={initialValues}>
            {(props) => (
              <Form onSubmit={handleLogin}>
                <span className="uname">
                  <Field
                    as={TextField}
                    label="Username"
                    name="email"
                    placeholder="Enter Username"
                    variant="standard"
                    fullWidth
                    required
                    color="success"
                    helperText={<ErrorMessage name="email" />}
                    type="email"
                    value={email}
                    onChange={(e) => setEmail(e.target.value)}
                  />
                </span>
                <span className="passwd">
                  <Field
                    as={TextField}
                    label="Password"
                    name="password"
                    placeholder="Enter Password"
                    variant="standard"
                    type="password"
                    fullWidth
                    required
                    color="success"
                    autoComplete="off"
                    helperText={<ErrorMessage name="password" />}
                    value={password}
                    onChange={(e) => setPassword(e.target.value)}
                  />
                </span>
                <span className="login-remember">
                  <Field
                    as={FormControlLabel}
                    name="remember"
                    control={<Checkbox color="success" />}
                    label="Remember me"
                  />
                </span>
                <span className="signin-button">
                  <Button
                    variant="contained"
                    type="submit"
                    color="success"
                    style={btnStyle}
                    fullWidth
                    disabled={props.isSubmitting}
                  >
                    {props.isSubmitting ? "Loading" : "Sign In"}
                  </Button>
                  {error && (
                    <span className="span">Wrong email or password</span>
                  )}
                </span>
              </Form>
            )}
          </Formik>
          <span className="endcontent">
            <Typography
              component={'div'}
              sx={{ fontFamily: "Roboto, sans-serif", marginTop: "25px" }}
            >
              <Link href="/forget-password"> Forgotten password?</Link>
            </Typography>
            <Typography
              component={'div'}
              sx={{ fontFamily: "Roboto, sans-serif" }}
            >
              {" "}
              New to this domain ?{" "}
              <Link onClick={() => handleChange("event", 1)}>Join now </Link>
            </Typography>
          </span>
        </Paper>
      </Grid>
    </Grid>
  );

Any idea how to resolve this ?

Udayendu
  • 409
  • 5
  • 12
  • 1
    Your options are (1) correct the markup or (2) disable the warnings and continue with incorrect markup. Which are you looking to do? What have you tried in that attempt? – David Aug 09 '22 at 11:51
  • I want to go with (1) to fix the markup. But how to do that ? I checked in many places and found that its an issue with React itself and has to be fixed by the maintainer itself. As mentioned https://stackoverflow.com/questions/41928567/div-cannot-appear-as-a-descendant-of-p, I have already tried that but still the same. – Udayendu Aug 09 '22 at 11:54
  • By editing the markup so that `

    ` is not a descendant of `

    ` (similarly with the rest of the warnings). Somewhere in your component structure you are incorrectly using either a `

    ` or a component which renders to a `

    ` as a placeholder for more complex content. Which is invalid. A `

    ` is a *paragraph*. It's meant to hold a paragraph of text. Edit your markup to reflect that.

    – David Aug 09 '22 at 11:57
  • First, check how the component is rendering by inspecting the element. Can you provide an example of your components to see how they are nested? – Akis Aug 09 '22 at 11:57
  • @Udayendu: *"and found that its an issue with React itself and has to be fixed by the maintainer"* - I don't see how that's the case, but if your assertion is that your code is correct and React must be broken then it's not really clear what you're asking. – David Aug 09 '22 at 12:00
  • @David, may be I am rendering it wrongly. I have updated some test codes for the reference. Any suggestion ? – Udayendu Aug 09 '22 at 12:29
  • 1
    @Udayendu: Given the code shown, that's an interesting question. Note that in the code shown, `` is an immediate child of ``. But in the error, the structure from parent to child for these is: `TabPanel -> div -> Box -> div -> Typography -> p -> Login` The problem is that `

    ` in that hierarchy. But I don't see from the code shown how that's being inserted into that structure. Unless there's some customization happening in the `` that isn't shown here? This could involve some more debugging on your part.

    – David Aug 09 '22 at 12:43
  • @David, you are correct. TabPanel is a function thats being used to handle the tab switch between Login/SignUp. I have added that to the code. You can take a look now. – Udayendu Aug 09 '22 at 13:26
  • 1
    Thanks @Akis for pointing to the rendering. The wrapper was going wrong but its working now :) – Udayendu Aug 09 '22 at 13:33
  • @Udayendu: Ah, that makes sense now. I thought `` would have been something built-in to MUI or something of that nature. Indeed, that `` would be the culprit. I would even suggest replacing the `` entirely, rather than changing its rendered component. Keeping the semantics of the structure/hierarchy sensible will go a long way for debugging and maintenance over time. Typography elements should really just be text (with minimal complexity), not high-level containers for all sorts of potential elements. – David Aug 09 '22 at 13:34
  • @David, yes will re-design this things soon once the initial prototyping will be done. Thanks for all the help :) – Udayendu Aug 09 '22 at 13:36
  • @Udayendu in your code you are using `` which seems like a bad practice if you have other lements that render into a `
    `, button or ``. I would strongly suggest to also change them to `
    `
    – Akis Aug 09 '22 at 13:46
  • @Akis, Thanks for the recommendation. I was actually using
    only but specifically for this issue I changed those to . But I will move them back.
    – Udayendu Aug 11 '22 at 09:34

1 Answers1

3

@David, thanks for explaining the flow. I was applying the change in the wrong place.

After adding component={"div"} in the TabPanel function, it started working as well.

The working code is:

function TabPanel(props) {
    const { children, value, index, ...other } = props;

    return (
      <div
        role="tabpanelswitch"
        hidden={value !== index}
        id={`tabpanel-${index}`}
        aria-labelledby={`tab-${index}`}
        {...other}
      >
        {value === index && (
          <Box>
            <Typography component={"div"}>{children}</Typography>
          </Box>
        )}
      </div>
    );
  }
Udayendu
  • 409
  • 5
  • 12