简体   繁体   中英

Add component inside TabPanel from Material UI React

I am trying to create a dashboard component using the material-ui tabs. I want in each tab a different component to be rendered, It works but I get this warning in the console dozen times when my page loads.

index.js:1 Warning: validateDOMNesting(...): <p> cannot appear as a descendant of <p>.
in p (created by ForwardRef(Typography))
in ForwardRef(Typography) (created by WithStyles(ForwardRef(Typography)))
in WithStyles(ForwardRef(Typography)) (at Overview.jsx:10)
in div (created by ForwardRef(Grid))
in ForwardRef(Grid) (created by WithStyles(ForwardRef(Grid)))
in WithStyles(ForwardRef(Grid)) (at Overview.jsx:9)
in div (created by ForwardRef(Container))
in ForwardRef(Container) (created by WithStyles(ForwardRef(Container)))
in WithStyles(ForwardRef(Container)) (at Overview.jsx:8)
in Overview (at Dashboard.jsx:78)
in p (created by ForwardRef(Typography))
in ForwardRef(Typography) (created by WithStyles(ForwardRef(Typography)))
in WithStyles(ForwardRef(Typography)) (at Dashboard.jsx:23)
in div (created by Styled(MuiBox))
in Styled(MuiBox) (at Dashboard.jsx:22)
in div (at Dashboard.jsx:14)
in TabPanel (at Dashboard.jsx:77)
in div (at Dashboard.jsx:64)
in Dashboard (created by Route)
in Route (at App.js:37)
in Switch (at App.js:24)
in div (at Layout.jsx:9)
in div (at Layout.jsx:7)
in Layout (at App.js:23)
in App (at src/index.js:13)
in Router (created by BrowserRouter)
in BrowserRouter (at src/index.js:12)

This is my dashboard component, and when I remove the "Overview" component I do not get this warning in the console. I tried surrounding it with "div", "p" and <> but nothing works.

import PropTypes from 'prop-types';
import { makeStyles } from '@material-ui/core/styles';
import Tabs from '@material-ui/core/Tabs';
import Tab from '@material-ui/core/Tab';
import Typography from '@material-ui/core/Typography';
import Box from '@material-ui/core/Box';
import Overview from './Overview';

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

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

TabPanel.propTypes = {
  children: PropTypes.node,
  index: PropTypes.any.isRequired,
  value: PropTypes.any.isRequired,
};

function a11yProps(index) {
  return {
    id: `vertical-tab-${index}`,
    'aria-controls': `vertical-tabpanel-${index}`,
  };
}

const useStyles = makeStyles((theme) => ({
  root: {
    flexGrow: 1,
    backgroundColor: theme.palette.background.paper,
    display: 'flex',
    height: '100%',
  },
  tabs: {
    borderRight: `1px solid ${theme.palette.divider}`,
  },
}));

export default function Dashboard() {
  const classes = useStyles();
  const [value, setValue] = React.useState(0);

  const handleChange = (event, newValue) => {
    setValue(newValue);
  };

  return (
    <div className={classes.root}>
      <Tabs
        orientation='vertical'
        variant='scrollable'
        value={value}
        onChange={handleChange}
        aria-label='Vertical tabs example'
        className={classes.tabs}
      >
        <Tab label='Overview' {...a11yProps(0)} />
        <Tab label='Pending' {...a11yProps(1)} />
        <Tab label='Declined' {...a11yProps(2)} />
      </Tabs>
      <TabPanel value={value} index={0}>
        <Overview />
      </TabPanel>
      <TabPanel value={value} index={1}>
        Item Two
      </TabPanel>
      <TabPanel value={value} index={2}>
        Item Three
      </TabPanel>
    </div>
  );
}

this is my Overview component

import React from 'react';
import { Typography, Container } from '@material-ui/core';
import Grid from '@material-ui/core/Grid';
import CompanyRequest from './CompanyRequest';

const Overview = () => {
  return (
    <Container>
      <Grid container>
        <Typography>Overview</Typography>
        <CompanyRequest></CompanyRequest>
      </Grid>
    </Container>
  );
};

export default Overview;


Thanks in advance

Actually you're rendering the children in Typography which by default renders a p tag. In Overview, you're using p somewhere so its semantically wrong to use paragraph inside paragraph. Solution: Use some other component instead of Typography or:

<Typography component="div">{children}</Typography>

You can use some other html tag as well instead of div.

Typography by default has a variant body1 which maps to a p tag.

Since you use Typography within TabPanel and then inside Overview you use Typograpghy again, it leads to a nesting of p tags which is semantically incorrect and hence the warning

You can change the variant of Typography using the component prop or completely remove its usage as child in Box component

<Box p={3}>
      {children}
</Box>

or

  <Box p={3}>
      <Typography component="div"> // use any other tag apart from p as component prop
          {children}
      </Typography>
  </Box>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM