From f7fc00cde269026dbfe88a44c7ac952b112d65f9 Mon Sep 17 00:00:00 2001 From: Michel Weststrate Date: Fri, 8 Apr 2022 11:10:29 -0700 Subject: [PATCH] Fix bug where high frequent updates could be skipped Summary: As reported in https://fb.workplace.com/groups/flippersupport/permalink/1346149929198995/, data updates would sometimes not render in DataTable. After some debugging, this happens when multiple updates are scheduled with high frequency, and is bug in the internal render scheduler. (it might be that this never triggered before React 18, but it was a lingering bug). Basically in the following sequence, no second render of the data table would happen: 1. emit update 2. schedule render 3. React renders 4. emit a second update 5. scheduler bails out because update is already scheduled 6. React useEffect will clear out the scheduler state that was causing the render at point 3. Now the second update never gets rendered out (well, not until something else causes a new render). The problem here is that the scheduler state should be immediately reset as soon as React starts rendering, so that any new incoming update should trigger a new render, even though useEffect of the first render didn't finish. New flow now becomes: 1. emit update 2. schedule render 3. React renders & clears out scheduler state 4. emit a second update 5. scheduler schedules fresh render 6. etc... Reviewed By: nikoant Differential Revision: D35501325 fbshipit-source-id: 8af58c0da7bb024f360b750c856865f220dc6272 --- .../src/data-source/DataSourceRendererVirtual.tsx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/desktop/flipper-plugin/src/data-source/DataSourceRendererVirtual.tsx b/desktop/flipper-plugin/src/data-source/DataSourceRendererVirtual.tsx index 4b0fc6eb0..c045bf5b6 100644 --- a/desktop/flipper-plugin/src/data-source/DataSourceRendererVirtual.tsx +++ b/desktop/flipper-plugin/src/data-source/DataSourceRendererVirtual.tsx @@ -258,10 +258,8 @@ export const DataSourceRendererVirtual: ( /** * Render finalization */ - useEffect(function renderCompleted() { - renderPending.current = UpdatePrio.NONE; - lastRender.current = Date.now(); - }); + renderPending.current = UpdatePrio.NONE; + lastRender.current = Date.now(); /** * Observer parent height