我正在使用material-ui
lib尝试我的应用。
我创建了一个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;
我在这里错了什么。请帮助我。
答案 0 :(得分:1)
只有一个问题。您为图标组件使用了错误的名称。它是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
在FirstPage
中变成@material-ui/icons
。