我对RTK查询有一个问题:我有一个封装表的第一个组件。当发生刷新时-例如,当我删除某些数据时-父组件接收数据并通过道具将其传递给子组件,但表永远不会更新。因此,删除的结果仍会显示在表格上。
什么是正确的“React/恢复”方法来生成表的刷新?
以下是一些代码:
const Results = (props) => {
const router = useRouter()
const { data, error, isError, isLoading, isFetching } = useGetItemsQuery();
if(isLoading) {
return (
<>
<Spinner animation="border" size="sm" role="status" />{' '} Please wait while Loading...
</>
)
}
if(isError) {
return (
<>
<Alert key="warning" variant="warning" style={{marginLeft: "10px"}}>
Warning - There was an error with the request : {error.error}
</Alert>
</>
)
}
const sizePerPageList = [
{
text: '5',
value: 5,
},
];
if (data){
return(
<>
<Card>
<Card.Body>
Traffic results
<TableResults data={data} sizePerPageList={sizePerPageList} />
</Card.Body>
</Card>
</>
)
}
}
export default Results;
对于表中的第二个组件:
const TableResults = (props) => {
console.log('props - data ', props.data);
const data = React.useMemo(
() => props.data,
[]
)
const columns = React.useMemo(
() => [
{
Header: 'bla bla',
accessor: 'blabla',
}
],
[]
)
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} />
</>
)
}
)
const {
getTableProps,
getTableBodyProps,
headerGroups,
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,
prepareRow,
state: { pageIndex, pageSize, selectedRowIds },
visibleColumns,
preGlobalFilteredRows,
setGlobalFilter,
selectedFlatRows
} = useTable({ columns, data }, useGlobalFilter, useFilters, useSortBy, 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,
])
} )
return (
<>
<DeleteItemButton items={selectedFlatRows} />
<BTable {...getTableProps()} striped bordered hover size="sm">
<thead>
{headerGroups.map(headerGroup => (
<tr {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map(column => (
<th
{...column.getHeaderProps(column.getSortByToggleProps())}
>
{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()}
style={{
// padding: '10px',
// border: 'solid 1px gray',
// background: 'papayawhip',
}}
>
{cell.render('Cell')}
</td>
)
})}
</tr>
)
})}
</tbody>
</BTable>
<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>
</>
)
}
export default TableResults;
DeleteItemButton将生成一个运行良好的简单RTK查询,并触发从主组件刷新数据:
deleteItems: builder.mutation({
query(data) {
// send array
let sanitized;
sanitized = keywords.filter(item => item);
const data = {
items: sanitized
}
//console.log('data: ', data);
return {
url: `items`,
method: 'DELETE',
body: data
}
},
invalidatesTags: ['Items']
}),
该应用程序在nextJS下运行。如有需要,敬请惠顾!
谢谢
1条答案
按热度按时间ndh0cuux1#
什么是正确的“React/恢复”方法来生成表的刷新?
刷新数据的正确方法是使用RTK查询的
providesTags
和invalidatesTags
特性,您已经在这样做了。您的表不刷新的原因是您显式地告诉它忽略对
props.data
的所有更改,并对所有后续呈现使用初始值。这显然不是你想要的,但这就是你在这里做的:具有空依赖项数组的
useMemo
将仅执行一次。一般来说,您在useMemo
中使用的所有变量都应该作为依赖项包括在内。因此,依赖数组应该是[props.data]
。当然,这个特定的
useMemo
不会“做任何事情”,可以安全地删除。如果您正在重新格式化props.data
变量,并且只想在props.data
的值更改时执行重新格式化,那么使用useMemo
将是有意义的。