[英]Material UI React Table Pagination
我想在 React UI Material 中查詢表格分頁。
在這里,我試圖實現來自 API 的所有數據。
我成功實現的一些數據是從API到Material UI Table。
但是,當我嘗試實現分頁時,數據無法從 API 正確顯示。
示例:組件第一次渲染時,會顯示來自 API 的 5 個數據。 但是當我嘗試移動到下一頁時,只有來自 API 的響應成功,而沒有出現的數據。
這里我把它分成幾個文件:
文件索引組件。
import React, { useState } from 'react'
// * Material UI
import {
Dialog,
DialogTitle,
DialogContent,
DialogContentText,
DialogActions,
Grid,
TableContainer,
Table,
TableHead,
TableRow,
TableCell,
TableBody,
TablePagination,
CssBaseline
} from '@material-ui/core'
import {
Add
} from '@material-ui/icons'
// * Core Component
import Layout from '@containers/v2/core/Layout'
import InputCategoryComponent from './Input'
import CardCore from '../../core/shared/Card'
import Controls from '../../core/shared/controls'
import { isEmpty } from '@client/libs/utils'
const columns = [
{ id: 'name', label: 'Name', minWidth: 500 },
{ id: 'Actions', label: 'Action', minWidth: 100 }
]
export default function CategoryComponent ({
page = 0,
rowsPerPage = 5,
rowsPerPageOptions = [5, 10, 15, 20, 25],
startDate = '',
endDate = '',
sortBy = 'created_at',
sortDirection = 'desc',
search = '',
totalCount = 0,
items = [],
fetch = () => {},
createPaymentCategory = () => {},
readPaymentCategory = () => {},
updatePaymentCategory = () => {},
deletePaymentCategory = () => {},
handleRowPerPage = () => {},
handlePagination = () => {}
}) {
const [isTable, setTable] = useState(true)
const [alert, setAlert] = useState(false)
const [hashed, setHashed] = useState('')
const [initialModel, setModel] = useState([])
const emptyRows = rowsPerPage - Math.min(rowsPerPage, totalCount - page * rowsPerPage)
const handleTable = (params) => {
setTable(params)
}
const handleAlertOpen = (payload) => {
setHashed(payload)
setAlert(true)
}
const handleChange = (payload) => {
if (isEmpty(payload)) {
setModel({
name: ''
})
setTable(false)
} else {
readPaymentCategory(payload).then((res) => {
setModel(res.data)
setTable(false)
})
}
}
const handleAlertClose = () => {
setAlert(false)
}
const onFinish = () => {
fetch(
page,
rowsPerPage,
startDate,
endDate,
sortBy,
sortDirection,
search
)
setTable(true)
setModel({
name: ''
})
}
const onDelete = () => {
deletePaymentCategory(hashed).then(() => {
setHashed('')
setAlert(false)
fetch(
page,
rowsPerPage,
startDate,
endDate,
sortBy,
sortDirection,
search
)
})
}
const onRowChange = (e) => {
handleRowPerPage(e.target.value)
fetch(
0,
e.target.value,
startDate,
endDate,
sortBy,
sortDirection,
search
)
}
const onPageChange = (event, newPage) => {
handlePagination(newPage)
fetch(
newPage,
rowsPerPage,
startDate,
endDate,
sortBy,
sortDirection,
search
)
}
return (
<Layout>
<CssBaseline />
{isTable && (
<Grid container>
<Grid item sm={12} md={12} lg={12}>
<CardCore
variant='info'
title='Payment Category'
>
<Grid container>
<Grid item sm={12} md={12} lg={!2}>
<Controls.Button
text='Create'
color='primary'
startIcon={<Add />}
onClick={() => handleChange()}
/>
</Grid>
</Grid>
<Grid container>
<Grid item sm={12} md={12} lg={!2}>
<TableContainer>
<Table stickyHeader aria-label='sticky table'>
<TableHead>
<TableRow>
{columns.map((column) => (
<TableCell
key={column.id}
align={column.align}
style={{ minWidth: column.minWidth }}
>
{column.label}
</TableCell>
))}
</TableRow>
</TableHead>
<TableBody>
{items.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage).map((row) => {
return (
<TableRow hover role='checkbox' tabIndex={-1} key={row.name}>
<TableCell>{row.name}</TableCell>
<TableCell align='left'>
<div>
<Controls.Button
text='Edit'
color='inherit'
onClick={() => handleChange(row.hashed_id)}
/>
<Controls.Button
text='Delete'
color='secondary'
onClick={() => handleAlertOpen(row.hashed_id)}
/>
</div>
</TableCell>
</TableRow>
)
})}
{emptyRows > 0 && (
<TableRow style={{ height: 53 * emptyRows }}>
<TableCell colSpan={6} />
</TableRow>
)}
</TableBody>
</Table>
</TableContainer>
<TablePagination
rowsPerPageOptions={rowsPerPageOptions}
component='div'
count={totalCount}
rowsPerPage={rowsPerPage}
page={page}
onChangePage={onPageChange}
onChangeRowsPerPage={onRowChange}
/>
</Grid>
</Grid>
</CardCore>
</Grid>
</Grid>
)}
<Dialog
open={alert}
onClose={handleAlertClose}
fullWidth
maxWidth='sm'
aria-labelledby='alert-dialog-title'
aria-describedby='alert-dialog-description'
>
<DialogTitle id='alert-dialog-title'>Are you sure want to delete this?</DialogTitle>
<DialogContent>
<DialogContentText id='alert-dialog-description'>
You wont be able to revert this!
</DialogContentText>
</DialogContent>
<DialogActions>
<Controls.Button
text='Disagree'
color='secondary'
onClick={handleAlertClose}
/>
<Controls.Button
text='Agree'
color='primary'
autoFocus
onClick={onDelete}
/>
</DialogActions>
</Dialog>
{!isTable && (
<InputCategoryComponent
controlTable={handleTable}
initialValues={initialModel}
callBack={onFinish}
createData={createPaymentCategory}
updateData={updatePaymentCategory}
/>
)}
</Layout>
)
}
文件索引容器。
import React, { Component } from 'react'
import { mapStateToProps, mapActions } from '@client/store'
import { connect } from 'react-redux'
// * Category Component
import CategoryComponent from '@components/v2/Payment/Category/Index'
class PaymentCategoryContainer extends Component {
constructor (props) {
super(props)
this.state = {
page: 0,
rowsPerPage: 5,
rowsPerPageOptions: [5, 10, 15, 20, 25],
startDate: '',
endDate: '',
sortBy: 'created_at',
sortDirection: 'desc',
search: '',
totalCount: 0,
items: []
}
this.fetch = this.fetch.bind(this)
this.handleRow = this.handleRow.bind(this)
this.handlePage = this.handlePage.bind(this)
}
fetch (page, rowsPerPage, startDate, endDate, sortBy, sortDirection, search) {
this.props.fetchPaymentCategory(
page,
rowsPerPage,
startDate,
endDate,
sortBy,
sortDirection,
search
).then((res) => {
if (res?.status === 200) {
this.setState({
items: res?.data.items,
totalCount: res?.data.totalItems
})
} else {
console.log('error')
}
})
}
handleRow (rowsPerPage) {
this.setState({
rowsPerPage: rowsPerPage
})
const { page, startDate, endDate, sortBy, sortDirection, search } = this.state
this.fetch(
page,
rowsPerPage,
startDate,
endDate,
sortBy,
sortDirection,
search
)
}
handlePage (numberOfPage) {
this.setState({
page: numberOfPage
})
const { rowsPerPage, startDate, endDate, sortBy, sortDirection, search } = this.state
this.fetch(
numberOfPage,
rowsPerPage,
startDate,
endDate,
sortBy,
sortDirection,
search
)
}
componentDidMount () {
this.fetch(
this.state.page,
this.state.rowsPerPage,
'',
'',
this.state.sortBy,
this.state.sortDirection,
''
)
}
render () {
return (
<CategoryComponent
{...this.props}
{...this.state}
fetch={this.fetch}
handleRowPerPage={this.handleRow}
handlePagination={this.handlePage}
/>
)
}
}
export default connect(
mapStateToProps('paymentCategory'),
mapActions(
'fetchPaymentCategory',
'changeRowPerPage',
'changePagination',
'createPaymentCategory',
'readPaymentCategory',
'updatePaymentCategory',
'deletePaymentCategory'
)
)(PaymentCategoryContainer)
來自 API 的響應數據:
items: [] => array. totalItems: 0 => int
有沒有我遺漏的錯誤? 還是我錯過了一步?。
我正在遵循本節 ui 材料中的示例。
謝謝你。
我找到了我犯的錯誤。 我不需要對數據進行slice()
。 因為我有一個 params 頁面查詢,所以我只需要map()
這樣的東西。
return (
<Layout>
<CssBaseline />
{isTable && (
<Grid container>
<Grid item sm={12} md={12} lg={12}>
<CardCore
variant='info'
title='Payment Category'
>
<Grid container>
<Grid item sm={12} md={12} lg={!2}>
<Controls.Button
text='Create'
color='primary'
startIcon={<Add />}
onClick={() => handleChange()}
/>
</Grid>
</Grid>
<Grid container>
<Grid item sm={12} md={12} lg={!2}>
<TableContainer>
<Table stickyHeader aria-label='sticky table'>
<TableHead>
<TableRow>
{columns.map((column) => (
<TableCell
key={column.id}
align={column.align}
style={{ minWidth: column.minWidth }}
>
{column.label}
</TableCell>
))}
</TableRow>
</TableHead>
<TableBody>
{items.map((row) => {
return (
<TableRow hover role='checkbox' tabIndex={-1} key={row.name}>
<TableCell>{row.name}</TableCell>
<TableCell align='left'>
<div>
<Controls.Button
text='Edit'
color='inherit'
onClick={() => handleChange(row.hashed_id)}
/>
<Controls.Button
text='Delete'
color='secondary'
onClick={() => handleAlertOpen(row.hashed_id)}
/>
</div>
</TableCell>
</TableRow>
)
})}
{emptyRows > 0 && (
<TableRow style={{ height: 53 * emptyRows }}>
<TableCell colSpan={6} />
</TableRow>
)}
</TableBody>
</Table>
</TableContainer>
<TablePagination
rowsPerPageOptions={rowsPerPageOptions}
component='div'
count={totalCount}
rowsPerPage={rowsPerPage}
page={page}
onChangePage={onPageChange}
onChangeRowsPerPage={onRowChange}
/>
</Grid>
</Grid>
</CardCore>
</Grid>
</Grid>
)}
<Dialog
open={alert}
onClose={handleAlertClose}
fullWidth
maxWidth='sm'
aria-labelledby='alert-dialog-title'
aria-describedby='alert-dialog-description'
>
<DialogTitle id='alert-dialog-title'>Are you sure want to delete this?</DialogTitle>
<DialogContent>
<DialogContentText id='alert-dialog-description'>
You wont be able to revert this!
</DialogContentText>
</DialogContent>
<DialogActions>
<Controls.Button
text='Disagree'
color='secondary'
onClick={handleAlertClose}
/>
<Controls.Button
text='Agree'
color='primary'
autoFocus
onClick={onDelete}
/>
</DialogActions>
</Dialog>
{!isTable && (
<InputCategoryComponent
controlTable={handleTable}
initialValues={initialModel}
callBack={onFinish}
createData={createPaymentCategory}
updateData={updatePaymentCategory}
/>
)}
</Layout>
)
}
希望這對其他人有幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.