From 0df426c203160b5e16415333c159f1396b6985fd Mon Sep 17 00:00:00 2001 From: Randy Schott <1815175+schottra@users.noreply.github.com> Date: Thu, 5 Nov 2020 16:38:34 -0800 Subject: [PATCH] fix: recompute row heights when new items are appended to DataList --- .../Tables/WorkflowExecutionsTable.tsx | 2 +- src/components/Tables/DataList.tsx | 48 +++++++++++++------ 2 files changed, 34 insertions(+), 16 deletions(-) diff --git a/src/components/Executions/Tables/WorkflowExecutionsTable.tsx b/src/components/Executions/Tables/WorkflowExecutionsTable.tsx index 7b50a3e59..ee2716869 100644 --- a/src/components/Executions/Tables/WorkflowExecutionsTable.tsx +++ b/src/components/Executions/Tables/WorkflowExecutionsTable.tsx @@ -239,7 +239,7 @@ export const WorkflowExecutionsTable: React.FC = p const listRef = React.useRef(null); // Reset error expansion states whenever list changes - React.useEffect(() => { + React.useLayoutEffect(() => { setExpandedErrors({}); }, [executions]); diff --git a/src/components/Tables/DataList.tsx b/src/components/Tables/DataList.tsx index 493b2cbd8..c03766a75 100644 --- a/src/components/Tables/DataList.tsx +++ b/src/components/Tables/DataList.tsx @@ -69,7 +69,21 @@ const DataListImplComponent: React.RefForwardingComponent< DataListRef, DataListImplProps > = (props, ref) => { + const { + height, + value: items, + lastError, + state, + moreItemsAvailable, + onScrollbarPresenceChange, + noRowsContent: NoRowsContent = 'No items found.', + rowContentRenderer, + width + } = props; + const styles = useStyles(); + const theme = useTheme(); + const lengthRef = React.useRef(0); const listRef = React.useRef(null); /** We want the cache to persist across renders, which useState will do. * But we also don't want to be needlessly creating new caches that are @@ -77,29 +91,33 @@ const DataListImplComponent: React.RefForwardingComponent< * will call to create the initial value. */ const [cellCache] = React.useState(createCellMeasurerCache); - const theme = useTheme(); - React.useImperativeHandle(ref, () => ({ - recomputeRowHeights: (rowIndex: number) => { + + const recomputeRow = React.useMemo( + () => (rowIndex: number) => { cellCache.clear(rowIndex, 0); if (listRef.current !== null) { listRef.current.recomputeRowHeights(rowIndex); } + }, + [cellCache, listRef] + ); + React.useImperativeHandle( + ref, + () => ({ + recomputeRowHeights: recomputeRow + }), + [recomputeRow] + ); + + React.useLayoutEffect(() => { + if (lengthRef.current >= 0 && items.length > lengthRef.current) { + recomputeRow(lengthRef.current); } - })); + lengthRef.current = props.value.length; + }, [items.length]); const headerHeight = theme.spacing(headerGridHeight); const listPadding = theme.spacing(tableGridPadding); - const { - height, - value: items, - lastError, - state, - moreItemsAvailable, - onScrollbarPresenceChange, - noRowsContent: NoRowsContent = 'No items found.', - rowContentRenderer, - width - } = props; const showLoadMore = items.length && moreItemsAvailable; // We want the "load more" content to render at the end of the list.