问题描述
我正在使用react-table
在表中包括行和分页,如下例所示:https://react-table.tanstack.com/docs/examples/row-selection-and-pagination。
我已经按照教程中的说明完成了示例,但是它没有按预期运行。在停止更新selectedRowsId
之前,我只能选择1行。取消选择该行也不会清除它。我在做什么错了?
import React,{ useMemo,forwardRef,useRef,useEffect } from "react";
import {
useTable,useSortBy,useFilters,useGlobalFilter,usePagination,useRowSelect
} from "react-table";
import matchSorter from "match-sorter";
import '../../static/scss/table.scss'
function DefaultColumnFilter({
column: { filterValue,preFilteredRows,setFilter },}) {
const count = preFilteredRows.length;
return (
<input
value={filterValue || ""}
onChange={(e) => {
setFilter(e.target.value || undefined); // Set undefined to remove the filter entirely
}}
placeholder={`Search ${count} records...`}
/>
);
}
function SelectColumnFilter({
column: { filterValue,setFilter,id },}) {
// Calculate the options for filtering
// using the preFilteredRows
const options = React.useMemo(() => {
const options = new Set();
preFilteredRows.forEach((row) => {
options.add(row.values[id]);
});
return [...options.values()];
},[id,preFilteredRows]);
// Render a multi-select Box
return (
<select
value={filterValue}
onChange={(e) => {
setFilter(e.target.value || undefined);
}}
>
<option value="">All</option>
{options.map((option,i) => (
<option key={i} value={option}>
{option}
</option>
))}
</select>
);
}
function fuzzyTextFilterFn(rows,id,filterValue) {
return matchSorter(rows,filterValue,{ keys: [(row) => row.values[id]] });
}
fuzzyTextFilterFn.autoRemove = (val) => !val;
const IndeterminateCheckBox = forwardRef(
({ indeterminate,...rest },ref) => {
const defaultRef = useRef()
const resolvedRef = ref || defaultRef
useEffect(() => {
resolvedRef.current.indeterminate = indeterminate
},[resolvedRef,indeterminate])
return (
<>
<input type="checkBox" ref={resolvedRef} {...rest} />
</>
)
}
)
export default function Table({ data }) {
console.log(data[0].title);
const filterTypes = useMemo(
() => ({
// Add a new fuzzyTextFilterFn filter type.
fuzzyText: fuzzyTextFilterFn,// Or,override the default text filter to use
// "startWith"
text: (rows,filterValue) => {
return rows.filter((row) => {
const rowValue = row.values[id];
return rowValue !== undefined
? String(rowValue)
.toLowerCase()
.startsWith(String(filterValue).toLowerCase())
: true;
});
},}),[]
);
const defaultColumn = useMemo(
() => ({
// Let's set up our default Filter UI
Filter: DefaultColumnFilter,[]
);
const columns = useMemo(
() => [
{
Header: "Naziv",accessor: "title",},{
Header: "Tip",accessor: "activity_type_id",Filter: SelectColumnFilter,filter: "includes",{
Header: "Datum",accessor: "start_time",{
Header: "Mjesto",accessor: "location",{
Header: "Organizator",accessor: "team_id",{
Header: "Odgovorna osoba",accessor: "user_id",],[]
);
const {
getTableProps,getTableBodyProps,headerGroups,page,prepareRow,canPrevIoUsPage,canNextPage,pageOptions,pageCount,gotoPage,nextPage,prevIoUsPage,setPageSize,selectedFlatRows,state: { pageIndex,pageSize,selectedRowIds },} = useTable(
{
columns,data,defaultColumn,filterTypes,initialState: { pageIndex: 0 },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,])
}
);
return (
<div>
<legend className="legend">Popis aktivnosti</legend>
<>
<pre>
<code>
{JSON.stringify(
{
pageIndex,null,2
)}
</code>
</pre>
<table {...getTableProps()}>
<thead>
{
// Loop over the header rows
headerGroups.map((headerGroup) => (
// Apply the header row props
<tr {...headerGroup.getHeaderGroupProps()}>
{
// Loop over the headers in each row
headerGroup.headers.map((column) => (
// Apply the header cell props
<th
{...column.getHeaderProps(
column.getSortByToggleProps()
)}
>
{
// Render the header
column.render("Header")
}
<span>
{column.isSorted
? column.isSortedDesc
? " ?"
: " ?"
: ""}
</span>
</th>
))
}
{}
<th>Nige</th>
<th>Nei</th>
</tr>
))
}
{
// Loop over the header rows
headerGroups.map((headerGroup) => (
// Apply the header row props
<tr {...headerGroup.getHeaderGroupProps()}>
{
// Loop over the headers in each row
headerGroup.headers.map((column) => (
// Apply the header cell props
<th>
<div>
{column.canFilter ? column.render("Filter") : null}
</div>
</th>
))
}
{}
<th></th>
<th></th>
</tr>
))
}
</thead>
{/* Apply the table body props */}
<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>
<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>
<p>Selected Rows: {Object.keys(selectedRowIds).length}</p>
<pre>
<code>
{JSON.stringify(
{
selectedRowIds: selectedRowIds,'selectedFlatRows[].original': selectedFlatRows.map(
d => d.original
),2
)}
</code>
</pre>
</>
</div>
);
}
解决方法
我找到了解决方案。 index.js文件的<React.StrictMode>
包装了<App />
。卸下<React.StrictMode>
可以对其进行修复并正常运行。这可能是一个错误,应该修复。