Таблица пользовательского интерфейса материала не реагирует при использовании примера адаптивного ящика

Я создал веб-приложение с базой из примера Material-UI на отзывчивый ящик

Я пытаюсь изменить размер таблицы в соответствии с шириной экрана, но по какой-то причине контейнер ResponsiveDrawer, предоставляемый Material-UI, нарушает отзывчивость содержимого (т.е. таблицы)

Вот пример, который я написал, отлично реагирует:

App.js

import React from "react";
import ReactDOM from "react-dom";
import Table from "@material-ui/core/Table/Table";
import TableHead from "@material-ui/core/TableHead/TableHead";
import TableRow from "@material-ui/core/TableRow/TableRow";
import TableCell from "@material-ui/core/TableCell/TableCell";
import TableBody from "@material-ui/core/TableBody/TableBody";
import Paper from "@material-ui/core/Paper/Paper";
import Grid from "@material-ui/core/Grid/Grid";

import "./styles.css";

function App() {
  return (
    <div className = "App">
      <Grid container justify = {"center"}>
        <Grid item xs = {12} md = {10} style = {{ padding: "8px" }}>
          <Paper style = {{ overflowX: "auto" }}>
            <Table style = {{ minWidth: "340px" }}>
              <TableHead>
                <TableRow>
                  <TableCell>Name</TableCell>
                  <TableCell>Column</TableCell>
                  <TableCell>Operating System</TableCell>
                  <TableCell>Status</TableCell>
                  <TableCell>CPU Cores</TableCell>
                  <TableCell>Memory (MB)</TableCell>
                  <TableCell>IP Address</TableCell>
                </TableRow>
              </TableHead>
              <TableBody>
                <TableRow>
                  <TableCell>Content</TableCell>
                  <TableCell>Content</TableCell>
                  <TableCell>Content</TableCell>
                  <TableCell>Content</TableCell>
                  <TableCell>Content</TableCell>
                  <TableCell>Content</TableCell>
                  <TableCell>Content</TableCell>
                </TableRow>
                <TableRow>
                  <TableCell>Content</TableCell>
                  <TableCell>Content</TableCell>
                  <TableCell>Content</TableCell>
                  <TableCell>Content</TableCell>
                  <TableCell>Content</TableCell>
                  <TableCell>Content</TableCell>
                  <TableCell>Content</TableCell>
                </TableRow>
              </TableBody>
            </Table>
          </Paper>
        </Grid>
      </Grid>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

И вот тот же пример с использованием модифицированной (изменено содержимое на this.props.children вместо статической) версии ResponsiveDrawer Material-UI.

ОтзывчивыйDrawer.js

import React from "react";
import PropTypes from "prop-types";
import AppBar from "@material-ui/core/AppBar";
import CssBaseline from "@material-ui/core/CssBaseline";
import Divider from "@material-ui/core/Divider";
import Drawer from "@material-ui/core/Drawer";
import Hidden from "@material-ui/core/Hidden";
import IconButton from "@material-ui/core/IconButton";
import InboxIcon from "@material-ui/icons/MoveToInbox";
import List from "@material-ui/core/List";
import ListItem from "@material-ui/core/ListItem";
import ListItemIcon from "@material-ui/core/ListItemIcon";
import ListItemText from "@material-ui/core/ListItemText";
import MailIcon from "@material-ui/icons/Mail";
import MenuIcon from "@material-ui/icons/Menu";
import Toolbar from "@material-ui/core/Toolbar";
import Typography from "@material-ui/core/Typography";
import { withStyles } from "@material-ui/core/styles";

const drawerWidth = 240;

const styles = theme => ({
  root: {
    display: "flex"
  },
  drawer: {
    [theme.breakpoints.up("sm")]: {
      width: drawerWidth,
      flexShrink: 0
    }
  },
  appBar: {
    marginLeft: drawerWidth,
    [theme.breakpoints.up("sm")]: {
      width: `calc(100% - ${drawerWidth}px)`
    }
  },
  menuButton: {
    marginRight: 20,
    [theme.breakpoints.up("sm")]: {
      display: "none"
    }
  },
  toolbar: theme.mixins.toolbar,
  drawerPaper: {
    width: drawerWidth
  },
  content: {
    flexGrow: 1,
    padding: theme.spacing.unit * 3
  }
});

class ResponsiveDrawer extends React.Component {
  state = {
    mobileOpen: false
  };

  handleDrawerToggle = () => {
    this.setState(state => ({ mobileOpen: !state.mobileOpen }));
  };

  render() {
    const { classes, theme } = this.props;

    const drawer = (
      <div>
        <div className = {classes.toolbar} />
        <Divider />
        <List>
          {["Inbox", "Starred", "Send email", "Drafts"].map((text, index) => (
            <ListItem button key = {text}>
              <ListItemIcon>
                {index % 2 === 0 ? <InboxIcon /> : <MailIcon />}
              </ListItemIcon>
              <ListItemText primary = {text} />
            </ListItem>
          ))}
        </List>
        <Divider />
        <List>
          {["All mail", "Trash", "Spam"].map((text, index) => (
            <ListItem button key = {text}>
              <ListItemIcon>
                {index % 2 === 0 ? <InboxIcon /> : <MailIcon />}
              </ListItemIcon>
              <ListItemText primary = {text} />
            </ListItem>
          ))}
        </List>
      </div>
    );

    return (
      <div className = {classes.root}>
        <CssBaseline />
        <AppBar position = "fixed" className = {classes.appBar}>
          <Toolbar>
            <IconButton
              color = "inherit"
              aria-label = "Open drawer"
              onClick = {this.handleDrawerToggle}
              className = {classes.menuButton}
            >
              <MenuIcon />
            </IconButton>
            <Typography variant = "h6" color = "inherit" noWrap>
              Responsive drawer
            </Typography>
          </Toolbar>
        </AppBar>
        <nav className = {classes.drawer}>
          {/* The implementation can be swapped with js to avoid SEO duplication of links. */}
          <Hidden smUp implementation = "css">
            <Drawer
              container = {this.props.container}
              variant = "temporary"
              anchor = {theme.direction === "rtl" ? "right" : "left"}
              open = {this.state.mobileOpen}
              onClose = {this.handleDrawerToggle}
              classes = {{
                paper: classes.drawerPaper
              }}
            >
              {drawer}
            </Drawer>
          </Hidden>
          <Hidden xsDown implementation = "css">
            <Drawer
              classes = {{
                paper: classes.drawerPaper
              }}
              variant = "permanent"
              open
            >
              {drawer}
            </Drawer>
          </Hidden>
        </nav>
        <main className = {classes.content}>
          <div className = {classes.toolbar} />
          {this.props.children}
        </main>
      </div>
    );
  }
}

ResponsiveDrawer.propTypes = {
  classes: PropTypes.object.isRequired,
  // Injected by the documentation to work in an iframe.
  // You won't need it on your project.
  container: PropTypes.object,
  theme: PropTypes.object.isRequired
};

export default withStyles(styles, { withTheme: true })(ResponsiveDrawer);

App.js

import React from "react";
import ReactDOM from "react-dom";
import Table from "@material-ui/core/Table/Table";
import TableHead from "@material-ui/core/TableHead/TableHead";
import TableRow from "@material-ui/core/TableRow/TableRow";
import TableCell from "@material-ui/core/TableCell/TableCell";
import TableBody from "@material-ui/core/TableBody/TableBody";
import Paper from "@material-ui/core/Paper/Paper";
import ResponsiveDrawer from "./ResponsiveDrawer";
import Grid from "@material-ui/core/Grid/Grid";

import "./styles.css";

function App() {
  return (
    <div className = "App">
      <ResponsiveDrawer>
        <Grid container justify = {"center"}>
          <Grid item xs = {12} md = {10} style = {{ padding: "8px" }}>
            <Paper style = {{ overflowX: "auto" }}>
              <Table style = {{ minWidth: "340px" }}>
                <TableHead>
                  <TableRow>
                    <TableCell>Name</TableCell>
                    <TableCell>Column</TableCell>
                    <TableCell>Operating System</TableCell>
                    <TableCell>Status</TableCell>
                    <TableCell>CPU Cores</TableCell>
                    <TableCell>Memory (MB)</TableCell>
                    <TableCell>IP Address</TableCell>
                  </TableRow>
                </TableHead>
                <TableBody>
                  <TableRow>
                    <TableCell>Content</TableCell>
                    <TableCell>Content</TableCell>
                    <TableCell>Content</TableCell>
                    <TableCell>Content</TableCell>
                    <TableCell>Content</TableCell>
                    <TableCell>Content</TableCell>
                    <TableCell>Content</TableCell>
                  </TableRow>
                  <TableRow>
                    <TableCell>Content</TableCell>
                    <TableCell>Content</TableCell>
                    <TableCell>Content</TableCell>
                    <TableCell>Content</TableCell>
                    <TableCell>Content</TableCell>
                    <TableCell>Content</TableCell>
                    <TableCell>Content</TableCell>
                  </TableRow>
                </TableBody>
              </Table>
            </Paper>
          </Grid>
        </Grid>
      </ResponsiveDrawer>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Я просто не могу понять, что именно внутри контейнера ResponsiveDrawer приводит к нарушению отзывчивости.

Любая помощь приветствуется.

ОБНОВЛЕНИЕ (07.01.2019): Похоже, удаление display: flex из корня решает проблему, но тогда у меня проблема в том, что он не учитывает левый ящик.

ОБНОВЛЕНИЕ (09.01.2019): Как было предложено @Gaurav Rana, я добавилwidth: 100%; для основного элемента, и это наполовину решило проблему. Теперь таблица будет переполняться / прокручиваться правильно, когда боковая панель не видна. Но когда боковая панель все еще видна, но экран недостаточно широк для всей таблицы, таблица прокручивается под боковой панелью.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
4
0
9 448
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

добавьте стиль ниже стиля в свой файл styles.css. надеюсь, это решит вашу проблему.

main {
  width: 100%;
}

Спасибо за ответ! Таким образом, это работает, когда экран находится ниже точки останова отображения ящика, но не работает, когда ящик присутствует codeandbox.io/s/6zl7r2lx0r

AKrush95 08.01.2019 16:36

измените это (<Grid item xs = {12} md = {10} style = {{padding: "8px"}}>) на (<Grid item xs = {12} style = {{padding: "8px"}} >) в index.js

Gaurav Rana 09.01.2019 07:02

спасибо за ответ, но это тоже не решило проблему. Проблема в том, что, когда боковая панель все еще видна, но ширина экрана достаточно мала, чтобы таблица не помещалась, таблица прокручивается под боковой панелью.

AKrush95 09.01.2019 15:00
Ответ принят как подходящий

После небольшого устранения неполадок я нашел решение:

Стили для content необходимо обновить следующим образом (при необходимости ширина элемента содержимого будет соответствовать ширине экрана без выдвижного ящика):

  content: {
    [theme.breakpoints.up("sm")]: {
      marginLeft: drawerWidth,
      width: `calc(100% - ${drawerWidth}px)`
    }
  },

И display: flex нужно удалить из root

https://codesandbox.io/s/1zxp2qjmoj

это проблема ширины css width. Вы должны указать целых родителей width: 100% следующим образом

body {
  width: 100%
}
.grandparent {
  width: 100%
}
.parent {
  width: 100%
}
.tableContainer {
  width: 100%
}

Другие вопросы по теме