代码之家  ›  专栏  ›  技术社区  ›  Thuan Nguyen

ReactJS:导入组件时出现材质ui错误

  •  2
  • Thuan Nguyen  · 技术社区  · 8 年前

    我正在尝试我的应用程序使用 material-ui 图书馆。

    我创造了一个 Table Custom Table Pagination Action ,但我得到了这样的错误。

    我得到的错误:

    Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
    
    Check the render method of `TablePaginationActions`.
        in TablePaginationActions (created by WithStyles(TablePaginationActions))
        in WithStyles(TablePaginationActions) (created by TablePagination)
    

    DataTables 组成部分:

    import React, { Component } from 'react';
    import PropTypes from 'prop-types';
    import { withStyles } from '@material-ui/core/styles';
    import {
      ListItem,
      TableFooter,
      TablePagination,
      ListItemText,
      Avatar,
      Table,
      TableBody,
      TableCell,
      TableHead,
      TableRow,
      Paper
    } from '@material-ui/core';
    
    import TablePaginationActionsWrapped from './TablePaginationActions'
    
    const CustomTableCell = withStyles(theme => ({
      body: {
        fontSize: 14,
        paddingRight: 0,
      },
      head: {
        paddingRight: 0,
      }
    }))(TableCell);
    
    const CustomTableRow = withStyles(theme => ({
      root: {},
    }))(TableRow);
    
    const CustomTableHead = withStyles(theme => ({
      root: {
        padding: '0'
      },
    }))(TableHead);
    
    const styles = theme => ({
      root: {
        width: '100%',
        marginTop: theme.spacing.unit * 3,
        overflowX: 'auto',
        borderRadius: '0'
      },
      table: {
        minWidth: 500,
      },
      tableWrapper: {
        overflowX: 'auto',
      },
    });
    
    class DataTables extends Component {
    
      state = {
        data: this.props.reportsList,
        page: 0,
        rowsPerPage: 10,
      }
    
      handleChangePage = (event, page) => {
        this.setState({page});
      };
    
      handleChangeRowsPerPage = event => {
        this.setState({rowsPerPage: event.target.value});
      };
    
      render() {
        const {classes, reportsList} = this.props;
        const {data, rowsPerPage, page} = this.state;
        const emptyRows = rowsPerPage - Math.min(rowsPerPage, data.length - page * rowsPerPage);
    
        return (
          <Paper className={classes.root}>
            <div className={classes.tableWrapper}>
              <Table className={classes.table}>
                <CustomTableHead>
                  <CustomTableRow>
                    <CustomTableCell>ID</CustomTableCell>
                    <CustomTableCell>Report Title</CustomTableCell>
                    <CustomTableCell>Author</CustomTableCell>
                    <CustomTableCell>Date created</CustomTableCell>
                  </CustomTableRow>
                </CustomTableHead>
                <TableBody>
                  {data.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage).map(report => {
                    return (
                      <CustomTableRow key={report.id}>
                        <CustomTableCell>{report.id}</CustomTableCell>
                        <CustomTableCell component="th" scope="row">
                          {report.title}
                        </CustomTableCell>
                        <CustomTableCell padding="none" component="th" scope="row">
                          <ListItem>
                            <Avatar alt="Avatar image" src={report.userId.avatar}/>
                            <ListItemText>{report.userId.firstName}</ListItemText>
                          </ListItem>
                        </CustomTableCell>
                        <CustomTableCell component="th" scope="row">
                          {report.date}
                        </CustomTableCell>
                      </CustomTableRow>
                    );
                  })}
                  {emptyRows > 0 && (
                    <TableRow style={{ height: 48 * emptyRows }}>
                      <TableCell colSpan={6} />
                    </TableRow>
                  )}
                </TableBody>
                <TableFooter>
                  <TableRow>
                    <TablePagination
                      colSpan={3}
                      count={reportsList.length}
                      rowsPerPage={this.state.rowsPerPage}
                      page={this.state.page}
                      onChangePage={this.handleChangePage}
                      onChangeRowsPerPage={this.handleChangeRowsPerPage}
                      ActionsComponent={TablePaginationActionsWrapped}
    
                      // ActionsComponent={TablePaginationActionsWrapped} If not use this, my app work fine.
                    />
                  </TableRow>
                </TableFooter>
              </Table>
            </div>
          </Paper>
        );
      }
    }
    
    DataTables.propTypes = {
      classes: PropTypes.object.isRequired,
    };
    
    export default withStyles(styles)(DataTables);
    

    还有我的 TablePaginationActionsWrapped 组成部分:

    import React, { Component } from 'react';
    import PropTypes from 'prop-types';
    import { withStyles } from '@material-ui/core/styles';
    import IconButton from '@material-ui/core/IconButton';
    import { FirstPageIcon, KeyboardArrowLeft, KeyboardArrowRight, LastPageIcon } from '@material-ui/icons'
    
    const actionsStyles = theme => ({
      root: {
        flexShrink: 0,
        color: theme.palette.text.secondary,
        marginLeft: theme.spacing.unit * 2.5,
      },
    });
    
    class TablePaginationActions extends Component {
    
      handleFirstPageButtonClick = event => {
        this.props.onChangePage(event, 0);
      };
    
      handleBackButtonClick = event => {
        this.props.onChangePage(event, this.props.page - 1);
      };
    
      handleNextButtonClick = event => {
        this.props.onChangePage(event, this.props.page + 1);
      };
    
      handleLastPageButtonClick = event => {
        this.props.onChangePage(
          event,
          Math.max(0, Math.ceil(this.props.count / this.props.rowsPerPage) - 1),
        );
      };
    
      render() {
    
        const { classes, count, page, rowsPerPage, theme } = this.props;
    
        return (
          <div className={classes.root}>
            <IconButton
              onClick={this.handleFirstPageButtonClick}
              disabled={page === 0}
              aria-label="First Page"
            >
              {theme.direction === 'rtl' ? <LastPageIcon /> : <FirstPageIcon />}
            </IconButton>
            <IconButton
              onClick={this.handleBackButtonClick}
              disabled={page === 0}
              aria-label="Previous Page"
            >
              {theme.direction === 'rtl' ? <KeyboardArrowRight /> : <KeyboardArrowLeft />}
            </IconButton>
            <IconButton
              onClick={this.handleNextButtonClick}
              disabled={page >= Math.ceil(count / rowsPerPage) - 1}
              aria-label="Next Page"
            >
              {theme.direction === 'rtl' ? <KeyboardArrowLeft /> : <KeyboardArrowRight />}
            </IconButton>
            <IconButton
              onClick={this.handleLastPageButtonClick}
              disabled={page >= Math.ceil(count / rowsPerPage) - 1}
              aria-label="Last Page"
            >
              {theme.direction === 'rtl' ? <FirstPageIcon /> : <LastPageIcon />}
            </IconButton>
          </div>
        );
      }
    }
    
    TablePaginationActions.propTypes = {
      classes: PropTypes.object.isRequired,
      count: PropTypes.number.isRequired,
      onChangePage: PropTypes.func.isRequired,
      page: PropTypes.number.isRequired,
      rowsPerPage: PropTypes.number.isRequired,
      theme: PropTypes.object.isRequired,
    };
    
    const TablePaginationActionsWrapped = withStyles(actionsStyles, { withTheme: true })(
      TablePaginationActions,
    );
    
    export default TablePaginationActionsWrapped;
    

    我做错了什么。请帮帮我。

    1 回复  |  直到 8 年前
        1
  •  1
  •   Sandip Nirmal    8 年前

    只有一个问题。您为图标组件使用了错误的名称。它是 LastPage 和 FirstPage 不 LastPageIcon 和 FirstPageIcon . 只要纠正它,它就会工作得很好。

    import React, { Component } from 'react'
    import PropTypes from 'prop-types'
    import { withStyles } from '@material-ui/core/styles'
    import IconButton from '@material-ui/core/IconButton'
    import { FirstPage, KeyboardArrowLeft, KeyboardArrowRight, LastPage } from '@material-ui/icons'
    
    const actionsStyles = theme => ({
      root: {
        flexShrink: 0,
        color: theme.palette.text.secondary,
        marginLeft: theme.spacing.unit * 2.5
      }
    })
    
    class TablePaginationActions extends Component {
      handleFirstPageButtonClick = event => {
        this
          .props
          .onChangePage(event, 0)
      }
    
      handleBackButtonClick = event => {
        this
          .props
          .onChangePage(event, this.props.page - 1)
      }
    
      handleNextButtonClick = event => {
        this
          .props
          .onChangePage(event, this.props.page + 1)
      }
    
      handleLastPageButtonClick = event => {
        this
          .props
          .onChangePage(event, Math.max(0, Math.ceil(this.props.count / this.props.rowsPerPage) - 1))
      }
    
      render() {
        const { classes, count, page, rowsPerPage, theme } = this.props
    
        return (
          <div className={classes.root}>
            <IconButton
              onClick={this.handleFirstPageButtonClick}
              disabled={page === 0}
              aria-label='First Page'>
              {theme.direction === 'rtl'
                ? <LastPage/>
                : <FirstPage />}
            </IconButton>
            <IconButton
              onClick={this.handleBackButtonClick}
              disabled={page === 0}
              aria-label='Previous Page'>
              {theme.direction === 'rtl'
                ? <KeyboardArrowRight />
                : <KeyboardArrowLeft />}
            </IconButton>
            <IconButton
              onClick={this.handleNextButtonClick}
              disabled={page >= Math.ceil(count / rowsPerPage) - 1}
              aria-label='Next Page'>
              {theme.direction === 'rtl'
                ? <KeyboardArrowLeft />
                : <KeyboardArrowRight />}
            </IconButton>
            <IconButton
              onClick={this.handleLastPageButtonClick}
              disabled={page >= Math.ceil(count / rowsPerPage) - 1}
              aria-label='Last Page' />
          </div>
        )
      }
    }
    
    TablePaginationActions.propTypes = {
      classes: PropTypes.object.isRequired,
      count: PropTypes.number.isRequired,
      onChangePage: PropTypes.func.isRequired,
      page: PropTypes.number.isRequired,
      rowsPerPage: PropTypes.number.isRequired,
      theme: PropTypes.object.isRequired
    }
    
    export default withStyles(actionsStyles, { withTheme: true })(TablePaginationActions)
    

    https://material.io/tools/icons/?icon=first_page&style=baseline . 你只需要把它转换成大写字母就可以了。喜欢的图标 first_page 首页 在里面 @material-ui/icons .