Material UI React 的数据驱动标签

Data driven Tabs with Material UI React

我想用我得到的数据数组渲染标签和标签面板。 我已经呈现了选项卡标题,但在单击选项卡时无法呈现 Tabpanel 数据。以下是我的代码。 如果选择日期选项卡,我想显示每个日期的影院。

我尝试了很多但都失败了。感谢您的建议。 谢谢...

import React from "react";
import PropTypes from "prop-types";
import { makeStyles } from "@material-ui/core/styles";
import AppBar from "@material-ui/core/AppBar";
import Tabs from "@material-ui/core/Tabs";
import Tab from "@material-ui/core/Tab";
import PhoneIcon from "@material-ui/icons/Phone";
import FavoriteIcon from "@material-ui/icons/Favorite";
import PersonPinIcon from "@material-ui/icons/PersonPin";
import HelpIcon from "@material-ui/icons/Help";
import ShoppingBasket from "@material-ui/icons/ShoppingBasket";
import ThumbDown from "@material-ui/icons/ThumbDown";
import ThumbUp from "@material-ui/icons/ThumbUp";
import Typography from "@material-ui/core/Typography";
import Box from "@material-ui/core/Box";
import { DateRangeSharp } from "@material-ui/icons";

const DATES = [
  {
    id: 1,
    day: "WED",
    date: 19,
    theater: [{ tname: "vista" }, { tname: "liberty" }],
  },
  {
    id: 2,
    day: "THU",
    date: 20,
    theater: [{ tname: "PVR" }, { tname: "CCC" }],
  },
  {
    id: 3,
    day: "FRI",
    date: 21,
    theater: [{ tname: "vista" }, { tname: "liberty" }],
  },
  { id: 4, day: "SAT", date: 22 },
  { id: 5, day: "SUN", date: 23 },
  { id: 6, day: "MON", date: 24 },
  { id: 7, day: "TUE", date: 25 },
  { id: 8, day: "WED", date: 26 },
];

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

  return (
    <div
      role="tabpanel"
      hidden={value !== index}
      id={`scrollable-force-tabpanel-${index}`}
      aria-labelledby={`scrollable-force-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: `scrollable-force-tab-${index}`,
    "aria-controls": `scrollable-force-tabpanel-${index}`,
  };
}

const useStyles = makeStyles((theme) => ({
  root: {
    flexGrow: 1,
    width: "100%",
    backgroundColor: theme.palette.background.paper,
  },
}));

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

  const handleChange = (event, newValue) => {
    setValue(newValue);
  };
  return (
    <div className={classes.root}>
      <AppBar
        position="static"
        style={{ background: "#333545", minHeight: 60 }}
      >
        <Tabs
          value={value}
          onChange={handleChange}
          variant="scrollable"
          scrollButtons="on"
          indicatorColor="secondary"
          textColor="primary"
          aria-label="scrollable force tabs example"
          style={{ minHeight: 60 }}
          wrapped
        >
          {DATES.map((showtdates) => {
            return (
              <Tab
                label={showtdates.date + " " + showtdates.day}
                {...a11yProps(0)}
                style={{ color: "#fff", fontSize: 20, minHeight: 60 }}
              />
            );
          })}
        </Tabs>
      </AppBar>
      <TabPanel value={value} index={0}>
        showtdates.theater
      </TabPanel>
    </div>
  );
}

对于 DATES 数组中的每一天,您必须创建一个 TabPanel 并将 indexvalue 作为属性传递。您可以通过映射 DATES 数组轻松地做到这一点。在您的地图功能中,您可以访问所有属性并显示剧院。

例如,我使用 material-ui 的 List 组件来列出影院。

这可能看起来像这样:

import React from "react";
import PropTypes from "prop-types";
import { makeStyles } from "@material-ui/core/styles";
import AppBar from "@material-ui/core/AppBar";
import Tabs from "@material-ui/core/Tabs";
import Tab from "@material-ui/core/Tab";
import PhoneIcon from "@material-ui/icons/Phone";
import FavoriteIcon from "@material-ui/icons/Favorite";
import PersonPinIcon from "@material-ui/icons/PersonPin";
import HelpIcon from "@material-ui/icons/Help";
import ShoppingBasket from "@material-ui/icons/ShoppingBasket";
import ThumbDown from "@material-ui/icons/ThumbDown";
import ThumbUp from "@material-ui/icons/ThumbUp";
import Typography from "@material-ui/core/Typography";
import Box from "@material-ui/core/Box";
import { DateRangeSharp } from "@material-ui/icons";
import { List, ListItem, ListItemText } from "@material-ui/core";

const DATES = [
  {
    id: 1,
    day: "WED",
    date: 19,
    theater: [{ tname: "vista" }, { tname: "liberty" }]
  },
  {
    id: 2,
    day: "THU",
    date: 20,
    theater: [{ tname: "PVR" }, { tname: "CCC" }]
  },
  {
    id: 3,
    day: "FRI",
    date: 21,
    theater: [{ tname: "vista" }, { tname: "liberty" }]
  },
  { id: 4, day: "SAT", date: 22 },
  { id: 5, day: "SUN", date: 23 },
  { id: 6, day: "MON", date: 24 },
  { id: 7, day: "TUE", date: 25 },
  { id: 8, day: "WED", date: 26 }
];

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

  return (
    <div
      role="tabpanel"
      hidden={value !== index}
      id={`scrollable-force-tabpanel-${index}`}
      aria-labelledby={`scrollable-force-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: `scrollable-force-tab-${index}`,
    "aria-controls": `scrollable-force-tabpanel-${index}`
  };
}

const useStyles = makeStyles((theme) => ({
  root: {
    flexGrow: 1,
    width: "100%",
    backgroundColor: theme.palette.background.paper
  }
}));

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

  const handleChange = (event, newValue) => {
    setValue(newValue);
  };
  return (
    <div className={classes.root}>
      <AppBar
        position="static"
        style={{ background: "#333545", minHeight: 60 }}
      >
        <Tabs
          value={value}
          onChange={handleChange}
          variant="scrollable"
          scrollButtons="on"
          indicatorColor="secondary"
          textColor="primary"
          aria-label="scrollable force tabs example"
          style={{ minHeight: 60 }}
          wrapped
        >
          {DATES.map((showtdates) => {
            return (
              <Tab
                label={showtdates.date + " " + showtdates.day}
                {...a11yProps(0)}
                style={{ color: "#fff", fontSize: 20, minHeight: 60 }}
              />
            );
          })}
        </Tabs>
      </AppBar>
      {/* map over dates and create TabPanel */}

      {DATES.map((date, idx) => {

        // check if theater property exists and create a list of theaters as an example
        const theaters = date.hasOwnProperty('theater')
          ? date.theater.map((theater) => (
              <ListItem>
                <ListItemText primary="Theater name" secondary={theater.tname} />
              </ListItem>
            ))
          : null;
          
        return (
          <TabPanel value={value} index={idx}>
            <List>{theaters}</List>
          </TabPanel>
        );
      })}
    </div>
  );
}

现场演示: