簡體   English   中英

Material UI React 表格​​分頁

[英]Material UI React Table Pagination

我想在 React UI Material 中查詢表格分頁。

在這里,我試圖實現來自 API 的所有數據。

我成功實現的一些數據是從API到Material UI Table。

  1. 根據請求 Rows Per Page 調出數據
  2. 調出數據來自我擁有的 API。

但是,當我嘗試實現分頁時,數據無法從 API 正確顯示。

示例:組件第一次渲染時,會顯示來自 API 的 5 個數據。 但是當我嘗試移動到下一頁時,只有來自 API 的響應成功,而沒有出現的數據。

這里我把它分成幾個文件:

  1. 索引組件
  2. 索引容器

文件索引組件。

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM