Fix InteractiveTable: React, less hooks rendered than previous render (#85043)

fix: react-hooks error if data length switches from above or below pageSize
This commit is contained in:
Adam Bannach 2024-03-25 06:53:45 -05:00 committed by GitHub
parent 40e73f389f
commit d7f739c8e5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 39 additions and 12 deletions

View File

@ -1,8 +1,11 @@
import { Meta, StoryFn, StoryObj } from '@storybook/react';
import React, { useCallback, useState } from 'react';
import React, { useCallback, useMemo, useState } from 'react';
import { InteractiveTable, CellProps, LinkButton } from '@grafana/ui';
import { Field } from '../Forms/Field';
import { Input } from '../Input/Input';
import { FetchDataArgs, InteractiveTableHeaderTooltip } from './InteractiveTable';
import mdx from './InteractiveTable.mdx';
@ -125,9 +128,9 @@ const meta: Meta<typeof InteractiveTable<CarData>> = {
argTypes: {},
};
type TableStory = StoryObj<typeof InteractiveTable<CarData>>;
type TableStoryObj = StoryObj<typeof InteractiveTable<CarData>>;
export const Basic: TableStory = {
export const Basic: TableStoryObj = {
args: {
columns: [
{
@ -169,7 +172,7 @@ const ExpandedCell = ({ car }: CarData) => {
return <p>{car}</p>;
};
export const WithRowExpansion: TableStory = {
export const WithRowExpansion: TableStoryObj = {
args: {
renderExpandedRow: ExpandedCell,
},
@ -216,11 +219,33 @@ export const WithCustomCell: StoryObj<typeof InteractiveTable<WithCustomCellData
},
};
export const WithPagination: TableStory = {
args: {
pageSize: 15,
data: pageableData,
},
export const WithPagination: StoryFn<typeof InteractiveTable> = (args) => {
const [filter, setFilter] = useState('');
const data = useMemo(() => {
if (filter) {
return pageableData.filter((d) => d.firstName.toLowerCase().includes(filter.toLowerCase()));
}
return pageableData;
}, [filter]);
return (
<>
<Field label={'Filter data'}>
<Input
placeholder={'Filter by first name'}
onChange={(event) => {
setFilter(event.currentTarget.value);
}}
/>
</Field>
<InteractiveTable {...args} data={data} />
</>
);
};
WithPagination.args = {
pageSize: 15,
};
const headerTooltips: Record<string, InteractiveTableHeaderTooltip> = {
@ -238,7 +263,7 @@ const headerTooltips: Record<string, InteractiveTableHeaderTooltip> = {
iconName: 'plus-square',
},
};
export const WithHeaderTooltips: TableStory = {
export const WithHeaderTooltips: TableStoryObj = {
args: {
headerTooltips,
},

View File

@ -141,6 +141,8 @@ interface BaseProps<TableData extends object> {
headerTooltips?: Record<string, InteractiveTableHeaderTooltip>;
/**
* Number of rows per page. A value of zero disables pagination. Defaults to 0.
* A React hooks error will be thrown if pageSize goes from greater than 0 to 0 or vice versa. If enabling pagination,
* make sure pageSize remains a non-zero value.
*/
pageSize?: number;
/**
@ -196,7 +198,7 @@ export function InteractiveTable<TableData extends object>({
const tableHooks: Array<PluginHook<TableData>> = [useSortBy, useExpanded];
const multiplePages = data.length > pageSize;
const paginationEnabled = pageSize > 0 && multiplePages;
const paginationEnabled = pageSize > 0;
if (paginationEnabled) {
tableHooks.push(usePagination);
@ -304,7 +306,7 @@ export function InteractiveTable<TableData extends object>({
})}
</tbody>
</table>
{paginationEnabled && (
{paginationEnabled && multiplePages && (
<span>
<Pagination
currentPage={tableInstance.state.pageIndex + 1}