From 5b8da55880bdbb7956e72bd9f35f2c6d2f737e64 Mon Sep 17 00:00:00 2001 From: mikebender Date: Tue, 15 Jul 2025 10:13:14 -0400 Subject: [PATCH] fix: Render loop occurring in React v18 - Have an `updateRevision` state property that will update when forceUpdate is called, so we actually have a state variable that changes - Similar to how Plotly handles data updates - Removed the old logic that would trigger a draw any time componentDidUpdate was called --- packages/grid/src/Grid.tsx | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/packages/grid/src/Grid.tsx b/packages/grid/src/Grid.tsx index dd8a9eea00..92ef6017f9 100644 --- a/packages/grid/src/Grid.tsx +++ b/packages/grid/src/Grid.tsx @@ -216,6 +216,9 @@ export type GridState = { * so we need to throw them in componentDidUpdate */ renderError?: unknown; + + /** What revision the grid is drawing. Automatically increments when a forceUpdate is called. */ + updateRevision: number; }; /** @@ -486,6 +489,9 @@ class Grid extends PureComponent { isStuckToBottom, isStuckToRight, + + /** What revision the grid is drawing. Automatically increments when a forceUpdate is called. */ + updateRevision: 0, }; } @@ -531,8 +537,6 @@ class Grid extends PureComponent { (changedProps.length === 1 && changedProps[0] === 'children')) && changedState.length === 0 ) { - // We should still draw the canvas though, as we may have been called with a `forceUpdate` - this.requestUpdateCanvas(); return; } @@ -1925,6 +1929,13 @@ class Grid extends PureComponent { this.forceUpdate(); } + forceUpdate(callback?: (() => void) | undefined): void { + this.setState(({ updateRevision = 0 }) => ({ + updateRevision: (updateRevision + 1) % Number.MAX_SAFE_INTEGER, + })); + super.forceUpdate(callback); + } + handleWheel(event: WheelEvent): void { this.notifyMouseHandlers('onWheel', event);