【问题标题】:Material UI React Table PaginationMaterial UI React 表格​​分页
【发布时间】:2021-01-27 17:28:11
【问题描述】:

我想咨询一下 React UI Material 中的表格分页。

我在这里尝试实现 API 中的所有数据。

我已经成功实现的一些数据是从 API 到 Material UI Table。

  1. 根据请求每页的行数显示数据
  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

有没有我遗漏的错误?还是我错过了一个步骤?。

我正在关注this部分ui材料中的示例。

谢谢。

【问题讨论】:

    标签: javascript reactjs material-ui


    【解决方案1】:

    我找到了我犯的错误。我不需要slice() 数据。因为我有一个参数页面查询,所以我只需要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>
      )
    }
    

    希望这对其他人有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-18
      • 2021-11-19
      • 2020-02-11
      • 2021-08-07
      • 2021-02-11
      相关资源
      最近更新 更多