From d7f739c8e517e5103d89a329f32d9cdfd58a0b5d Mon Sep 17 00:00:00 2001 From: Adam Bannach <113929542+abannachGrafana@users.noreply.github.com> Date: Mon, 25 Mar 2024 06:53:45 -0500 Subject: [PATCH] Fix InteractiveTable: React, less hooks rendered than previous render (#85043) fix: react-hooks error if data length switches from above or below pageSize --- .../InteractiveTable.story.tsx | 45 ++++++++++++++----- .../InteractiveTable/InteractiveTable.tsx | 6 ++- 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/packages/grafana-ui/src/components/InteractiveTable/InteractiveTable.story.tsx b/packages/grafana-ui/src/components/InteractiveTable/InteractiveTable.story.tsx index 8993d20c2bd..c4deeb1ed4a 100644 --- a/packages/grafana-ui/src/components/InteractiveTable/InteractiveTable.story.tsx +++ b/packages/grafana-ui/src/components/InteractiveTable/InteractiveTable.story.tsx @@ -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> = { argTypes: {}, }; -type TableStory = StoryObj>; +type TableStoryObj = StoryObj>; -export const Basic: TableStory = { +export const Basic: TableStoryObj = { args: { columns: [ { @@ -169,7 +172,7 @@ const ExpandedCell = ({ car }: CarData) => { return

{car}

; }; -export const WithRowExpansion: TableStory = { +export const WithRowExpansion: TableStoryObj = { args: { renderExpandedRow: ExpandedCell, }, @@ -216,11 +219,33 @@ export const WithCustomCell: StoryObj = (args) => { + const [filter, setFilter] = useState(''); + + const data = useMemo(() => { + if (filter) { + return pageableData.filter((d) => d.firstName.toLowerCase().includes(filter.toLowerCase())); + } + return pageableData; + }, [filter]); + + return ( + <> + + { + setFilter(event.currentTarget.value); + }} + /> + + + + ); +}; + +WithPagination.args = { + pageSize: 15, }; const headerTooltips: Record = { @@ -238,7 +263,7 @@ const headerTooltips: Record = { iconName: 'plus-square', }, }; -export const WithHeaderTooltips: TableStory = { +export const WithHeaderTooltips: TableStoryObj = { args: { headerTooltips, }, diff --git a/packages/grafana-ui/src/components/InteractiveTable/InteractiveTable.tsx b/packages/grafana-ui/src/components/InteractiveTable/InteractiveTable.tsx index c66a1fe7439..a1ced1b5d0c 100644 --- a/packages/grafana-ui/src/components/InteractiveTable/InteractiveTable.tsx +++ b/packages/grafana-ui/src/components/InteractiveTable/InteractiveTable.tsx @@ -141,6 +141,8 @@ interface BaseProps { headerTooltips?: Record; /** * 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({ const tableHooks: Array> = [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({ })} - {paginationEnabled && ( + {paginationEnabled && multiplePages && (