javascript - react-table:使用分页重新渲染 UI
问题描述
我正在尝试从 react-table 文档中实现一个 react-table 分页示例。我也在使用 react-redux 来管理数据。该表显示正常,但只要单击任何分页控件,页面就会刷新,useEffect()
被调用,并且 react-table 重新呈现并重置为其初始分页状态。我正在使用React.useMemo()
,但 UI 仍然会重新渲染。我想知道在与分页控件交互时如何防止页面刷新。
我的示例代码:
import React, { useState, useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { userActions } from './actions';
import { useTable, usePagination, useRowSelect } from 'react-table'
function Products() {
const allProducts = useSelector(state => state.users.allProducts);
const memorizedProducts = React.useMemo(() => allProducts, [allProducts]);
const dispatch = useDispatch();
useEffect(() => {
dispatch(userActions.getAllProducts());
}, []);
const columns = React.useMemo(
() => [
{
Header: 'Id',
accessor: 'cell.productId',
},
{
Header: 'Name',
accessor: 'cell.name',
}
],
[]
);
return (
<ProductsTable columns={columns} data={memorizedProducts}/>
);
}
const ProductsTable = ({columns, data}) => {
if (!data) {
return null;
}
// Use the state and functions returned from useTable to build your UI
const {
getTableProps,
getTableBodyProps,
headerGroups,
prepareRow,
page, // Instead of using 'rows', we'll use page,
// which has only the rows for the active page
// The rest of these things are super handy, too ;)
canPreviousPage,
canNextPage,
pageOptions,
pageCount,
gotoPage,
nextPage,
previousPage,
setPageSize,
selectedFlatRows,
state: { pageIndex, pageSize, selectedRowIds },
} = useTable(
{
columns,
data,
},
usePagination,
useRowSelect,
hooks => {
hooks.visibleColumns.push(columns => [
// Let's make a column for selection
{
id: 'selection',
// The header can use the table's getToggleAllRowsSelectedProps method
// to render a checkbox
Header: ({ getToggleAllPageRowsSelectedProps }) => (
<div>
<IndeterminateCheckbox {...getToggleAllPageRowsSelectedProps()} />
</div>
),
// The cell can use the individual row's getToggleRowSelectedProps method
// to the render a checkbox
Cell: ({ row }) => (
<div>
<IndeterminateCheckbox {...row.getToggleRowSelectedProps()} />
</div>
),
},
...columns,
])
}
)
// Render the UI for your table
return (
<>
<div className="productsListDiv">
<table {...getTableProps()}>
<thead>
{headerGroups.map(headerGroup => (
<tr {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map(column => (
<th {...column.getHeaderProps()}>{column.render('Header')}</th>
))}
</tr>
))}
</thead>
<tbody {...getTableBodyProps()}>
{page.map((row, i) => {
prepareRow(row)
return (
<tr {...row.getRowProps()}>
{row.cells.map(cell => {
return <td {...cell.getCellProps()}>{cell.render('Cell')}</td>
})}
</tr>
)
})}
</tbody>
</table>
{/*
Pagination can be built however you'd like.
This is just a very basic UI implementation:
*/}
<div className="pagination">
<button onClick={() => gotoPage(0)} disabled={!canPreviousPage}>
{'<<'}
</button>{' '}
<button onClick={() => previousPage()} disabled={!canPreviousPage}>
{'<'}
</button>{' '}
<button onClick={() => nextPage()} disabled={!canNextPage}>
{'>'}
</button>{' '}
<button onClick={() => gotoPage(pageCount - 1)} disabled={!canNextPage}>
{'>>'}
</button>{' '}
<span>
Page{' '}
<strong>
{pageIndex + 1} of {pageOptions.length}
</strong>{' '}
</span>
<span>
| Go to page:{' '}
<input
type="number"
defaultValue={pageIndex + 1}
onChange={e => {
const page = e.target.value ? Number(e.target.value) - 1 : 0
gotoPage(page)
}}
style={{ width: '100px' }}
/>
</span>{' '}
<select
value={pageSize}
onChange={e => {
setPageSize(Number(e.target.value))
}}
>
{[10, 20, 30, 40, 50].map(pageSize => (
<option key={pageSize} value={pageSize}>
Show {pageSize}
</option>
))}
</select>
</div>
</div>
</>
);
}
const IndeterminateCheckbox = React.forwardRef(
({ indeterminate, ...rest }, ref) => {
const defaultRef = React.useRef()
const resolvedRef = ref || defaultRef
React.useEffect(() => {
resolvedRef.current.indeterminate = indeterminate
}, [resolvedRef, indeterminate])
return (
<>
<input type="checkbox" ref={resolvedRef} {...rest} />
</>
)
}
)
解决方案
推荐阅读
- android - 如何使用 Volley 在 GET 请求中发送正文
- grpc - 在 K6 中,我们可以在不指定端口号的情况下连接到 GRPC 服务吗?
- java - 如何从数据库中获取 300 万条记录并生成 CSV 文件
- docker - Dockerfile dotnet/sdk/5.0 错误 - container_linux.go:380:启动容器进程导致:exec:“cmd”:$PATH 中找不到可执行文件
- javascript - 从 d3.js 中的 json API 绘制地图?
- javascript - DOMContentLoaded 将在我的页面上触发两次
- javascript - 无法暂停动画 SVG
- kotlin - 期望成员声明(当使用来自另一个类的变量时会发生这种情况)
- kotlin - 在 Kotlin 中使用枚举验证方法调用
- android - 如何打印颤振的pdf文件