Skip to content

Commit

Permalink
feat: improve rerenders
Browse files Browse the repository at this point in the history
  • Loading branch information
mguellsegarra committed Sep 20, 2024
1 parent 539b4dd commit eff90b3
Showing 1 changed file with 47 additions and 13 deletions.
60 changes: 47 additions & 13 deletions src/components/InfiniteTable/InfiniteTable.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
forwardRef,
memo,
ReactNode,
useCallback,
useEffect,
useImperativeHandle,
Expand All @@ -26,6 +27,7 @@ import { HeaderCheckbox } from "./HeaderCheckbox";
import { useRowSelection } from "./useRowSelection";
import { areStatesEqual, useColumnState } from "./useColumnState";
import { CHECKBOX_COLUMN, STATUS_COLUMN } from "./columnStateHelper";
import debounce from "lodash/debounce";

const DEBOUNCE_TIME = 100;
const DEFAULT_TOTAL_ROWS_VALUE = Number.MAX_SAFE_INTEGER;
Expand All @@ -52,11 +54,11 @@ export type InfiniteTableProps = Omit<
totalRows?: number;
allRowSelectedMode?: boolean;
onAllRowSelectedModeChange?: (allRowSelectedMode: boolean) => void;
footer?: React.ReactNode;
footer?: ReactNode;
footerHeight?: number;
hasStatusColumn?: boolean;
onRowStatus?: (item: any) => any;
statusComponent?: (status: any) => React.ReactNode;
statusComponent?: (status: any) => ReactNode;
};

export type InfiniteTableRef = {
Expand Down Expand Up @@ -189,6 +191,12 @@ const InfiniteTableComp = forwardRef<InfiniteTableRef, InfiniteTableProps>(
return sortFields;
}, []);

const MemoizedStatusComponent = useMemo(() => {
if (!statusComponent) return undefined;
// eslint-disable-next-line react/display-name
return memo((props: { status: any }) => statusComponent(props.status));
}, [statusComponent]);

const colDefs = useMemo((): ColDef[] => {
const checkboxColumn = {
checkboxSelection: true,
Expand Down Expand Up @@ -244,7 +252,9 @@ const InfiniteTableComp = forwardRef<InfiniteTableRef, InfiniteTableProps>(
pinned: "left",
resizable: false,
headerComponent: () => null,
cellRenderer: (cell: any) => statusComponent?.(cell.value),
cellRenderer: MemoizedStatusComponent
? (cell: any) => <MemoizedStatusComponent status={cell.value} />
: undefined,
} as ColDef;

const finalColumns = [
Expand All @@ -261,7 +271,7 @@ const InfiniteTableComp = forwardRef<InfiniteTableRef, InfiniteTableProps>(
hasStatusColumn,
internalSelectedRowKeys.length,
onHeaderCheckboxChange,
statusComponent,
MemoizedStatusComponent,
totalRows,
]);

Expand All @@ -272,6 +282,15 @@ const InfiniteTableComp = forwardRef<InfiniteTableRef, InfiniteTableProps>(
}
}, [onGetFirstVisibleRowIndex]);

const memoizedOnRowStatus = useCallback(
(item: any) => {
if (onRowStatus) {
return onRowStatus(item);
}
return undefined;
},
[onRowStatus],
);
const getRows = useCallback(
async (params: IGetRowsParams) => {
gridRef.current?.api.showLoadingOverlay();
Expand All @@ -295,7 +314,9 @@ const InfiniteTableComp = forwardRef<InfiniteTableRef, InfiniteTableProps>(
const finalData = hasStatusColumn
? await Promise.all(
data.map(async (item) => {
const status = await onRowStatus?.(item);
const status = memoizedOnRowStatus
? await memoizedOnRowStatus(item)
: undefined;
return {
...item,
$status: status,
Expand Down Expand Up @@ -336,9 +357,9 @@ const InfiniteTableComp = forwardRef<InfiniteTableRef, InfiniteTableProps>(
[
getSortedFields,
hasStatusColumn,
memoizedOnRowStatus,
onGetSelectedRowKeys,
onRequestData,
onRowStatus,
scrollToSavedPosition,
selectedRowKeysPendingToRender,
setSelectedRowKeysPendingToRender,
Expand All @@ -355,22 +376,23 @@ const InfiniteTableComp = forwardRef<InfiniteTableRef, InfiniteTableProps>(
[getRows, loadPersistedColumnState],
);

const onRowDoubleClicked = useCallback(
const memoizedOnRowDoubleClick = useCallback(
({ data: item }: RowDoubleClickedEvent) => {
onRowDoubleClick?.(item);
},
[onRowDoubleClick],
);

const onBodyScroll = useCallback(
(params: BodyScrollEvent) => {
// eslint-disable-next-line react-hooks/exhaustive-deps
const debouncedOnBodyScroll = useCallback(
debounce((params: BodyScrollEvent) => {
if (!firstTimeOnBodyScroll.current) {
onChangeFirstVisibleRowIndex?.(
params.api.getFirstDisplayedRowIndex(),
);
}
firstTimeOnBodyScroll.current = false;
},
}, DEBOUNCE_TIME),
[onChangeFirstVisibleRowIndex],
);

Expand All @@ -390,7 +412,7 @@ const InfiniteTableComp = forwardRef<InfiniteTableRef, InfiniteTableProps>(
<AgGridReact
ref={gridRef}
columnDefs={colDefs}
onRowDoubleClicked={onRowDoubleClicked}
onRowDoubleClicked={memoizedOnRowDoubleClick}
rowStyle={{
cursor: onRowDoubleClick ? "pointer" : "auto",
}}
Expand All @@ -409,7 +431,7 @@ const InfiniteTableComp = forwardRef<InfiniteTableRef, InfiniteTableProps>(
infiniteInitialRowCount={50}
maxBlocksInCache={20}
onGridReady={onGridReady}
onBodyScroll={onBodyScroll}
onBodyScroll={debouncedOnBodyScroll}
blockLoadDebounceMillis={DEBOUNCE_TIME}
suppressDragLeaveHidesColumns={true}
/>
Expand All @@ -422,4 +444,16 @@ const InfiniteTableComp = forwardRef<InfiniteTableRef, InfiniteTableProps>(

InfiniteTableComp.displayName = "InfiniteTable";

export const InfiniteTable = memo(InfiniteTableComp);
export const InfiniteTable = memo(InfiniteTableComp, (prevProps, nextProps) => {
return (
prevProps.onRowDoubleClick === nextProps.onRowDoubleClick &&
prevProps.onGetFirstVisibleRowIndex ===
nextProps.onGetFirstVisibleRowIndex &&
prevProps.onGetSelectedRowKeys === nextProps.onGetSelectedRowKeys &&
prevProps.onRowStatus === nextProps.onRowStatus &&
prevProps.statusComponent === nextProps.statusComponent &&
prevProps.columns === nextProps.columns &&
prevProps.totalRows === nextProps.totalRows &&
prevProps.allRowSelectedMode === nextProps.allRowSelectedMode
);
});

0 comments on commit eff90b3

Please sign in to comment.