【问题标题】:Datatables.net: Correct serverside pagination with React ReduxDatatables.net:使用 React Redux 更正服务器端分页
【发布时间】:2023-03-11 14:14:01
【问题描述】:

我有一个 react 组件,它使用 redux 向 API 发出请求。此请求执行服务器端分页。

问题是我不明白如何使用 redux 在 datatables.net 中执行此分页。

我确实知道如何在没有数据表的情况下执行分页(实际上,我的组件正在执行它)并且数据表有一个ajax support,作为react-redux-datatable 包。两者都是通过 ajax 直接调用 API,而使用 redux 则不然。

import React, { useEffect, useState, useCallback } from 'react'
import { bindActionCreators } from 'redux'

//...

const [skip, setSkip] = useState(10)
const [page, setPage] = useState(0)

// offset = 0 to page 0, offset 10 to page 1, offset 20 to page 2 and so on
<button onClick={() => props.doList({ offset: page * skip  })}>Request</button>

// Table shows the current 10 entries, from a max that is also 10.
<Table data={props.list} columns={predefinedColums}>

//...

// results are acessed by props.list
const mapStateToProps = (state) => {
    return ({
        list: state.reducer.list,
    })
}

const mapDispatchToProps = dispatch =>
    bindActionCreators(
        {
            doList,
        },
        dispatch
    )

目前,我可以显示所需的结果,但不知道如何在数据表组件中对页面更改执行新调用。分页 API 正在工作,所以如果我手动更改页码,它会返回正确的条目。


//Table component

import React, { useEffect } from 'react'
import $ from 'jquery'
import 'datatables.net'
import 'datatables.net-responsive'
import 'datatables.net-select'

// other imports

function Table(props) {
    const { columns, data, title } = props

    useEffect(() => {
        $('#table_id').DataTable().destroy()
        $('#table_id').DataTable({
            retrieve: true,
            data,
            columns,
            "responsive": true,
            "lengthMenu": [
                [10, 25, 50, -1],
                [10, 25, 50, "All"]
            ],
            "language": {
                "emptyTable": i18n.t('emptyDataSourceMessage'),
                "paginate": {
                    "previous": i18n.t('Previous'),
                    "next": i18n.t('Next'),
                    "first": i18n.t("First"),
                    "last": i18n.t("Last"),
                },
                "infoFiltered": i18n.t("(filtered from _MAX_ total entries)"),
                "search": i18n.t('Search'),
                "info": i18n.t("Showing _START_ to _END_ of _TOTAL_ entries"),
                "infoEmpty": i18n.t("Showing 0 to 0 of 0 entries"),
            },
        })
    }, [columns, data])

    return (
        <div className="row">
            <div className="col s12">
                <div class="section section-data-tables">
                    <div className="card">
                        <div className="card-content">
                            <h4 className="card-title">{title}</h4>
                            <div className="row">
                                <div className="col s12">
                                    <table id="table_id" className="display">
                                        <thead>
                                            <tr>
                                                {columns.map((column, key) => <th key={key} data-field={column.field}>{column.title}</th>)}
                                            </tr>
                                        </thead>
                                        <tbody>
                                        </tbody>
                                        <tfoot>
                                            <tr>
                                                {columns.map((column, key) => <th key={key} data-field={column.field}>{column.title}</th>)}
                                            </tr>
                                        </tfoot>
                                    </table>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    )
}

export default Table

表格看起来像:(显示 10 个结果的 10 和唯一的页面)

我想知道如何使用 redux 正确执行服务器端分页。目前可以知道条目的数量以及要显示的当前页面。

【问题讨论】:

  • 如果服务器正在进行分页,那么在每个请求中它应该告诉总共有多少条目,你使用的限制是什么,你所在的页面是什么,可能是否有下一个页面与否,这将解决如何在 Redux 中执行此操作,如果您从 API 获得这些信息,我很确定您可以处理其余部分。
  • 是的,问题实际上在于使用 redux,因为使用 ajax 属性可以轻松实现分页本身。通过使用 redux,就像让数据准备好使用,但只是一页而不是让所有数据在前端分页。由于我可以拥有一百万个寄存器,因此获取所有数据并不合适。

标签: reactjs redux datatables pagination


【解决方案1】:

只需切出您想要返回给客户端的部分结果(请参阅下面的第一个代码部分)。 此外,我在进行服务器端分页时所做的是使用唯一 id 缓存请求的结果。这几乎是强制性的,以防止每次用户切换页码或页面大小时多次重新计算搜索。

我要求一些结果如下:

  1. 客户端:发送搜索(也可以是类别id)请求。

  2. 服务器:将搜索转换为唯一 ID。查看结果是否已经在缓存中。如果否,则计算搜索,放入缓存中,键为唯一 ID。对搜索结果使用常用的数组操作(切片),我只取想要的部分。

ret.productIDs =ret.productIDs.slice(imports.config.pageSizes[req.body.pageSize]*(req.body.pageNum), imports.config.pageSizes[req.body.pageSize]*(req.body.pageNum+1));
  1. 服务器:将其与搜索唯一 ID 一起返回(以便下次它可以直接使用此 ID 而不是搜索)。

  2. 客户端:显示搜索结果。每当用户更改页面大小或页面编号时,发送此请求:

    {
        searchId, pageNum, pageSizeIndex
    }
    

现在您还可以使用排序索引将其扩展到排序。另外,在服务器上,您可以记录缓存中搜索结果的可用排序。如果用户要求的排序尚未计算,只需对可用排序之一(已计算排序)进行排序,并将其添加到缓存条目的可用排序中(对于此搜索结果)。 所以最终的请求实际上是这样的:

{
    searchId, pageNum, pageSizeIndex, sortingIndex
}

【讨论】:

  • 似乎是另一种选择,但似乎它使请求不那么灵活,例如,使用搜索字段,这可能会更改缓存规则,除非我也将这个缓存规则缓存在单个 ID 中。
  • 好吧,我不确定我是否说清楚了,我也不确定是什么困扰着您^^ 如果您忘记缓存,并专注于分页方面,只是在搜索结果上使用 slice 来切割用户需要的部分,更好吗?然后,请求将如下所示:{ search(或 categoryId,或任何对您想要获取的数据进行分类的内容)、pageNum、pageSizeIndex }
  • 问题实际上是使用redux,而不是分页本身。在使用 redux 时,我需要一些事件来触发获取下一页的新请求,它可以很好地作为 API 调用。问题是我无法将 redux 调用绑定到页面按钮中的单击(作为“更改”触发器)
  • 那我可以建议你看看Redux Real World Example 吗?它展示了如何使用分页,看看pagination reducer
  • 还有here
猜你喜欢
  • 1970-01-01
  • 2016-03-26
  • 2020-02-26
  • 2021-03-21
  • 1970-01-01
  • 2016-11-21
  • 2018-03-29
  • 2016-05-04
相关资源
最近更新 更多