@@ -10,6 +10,8 @@ import {
1010 restoreStateIfNeeded ,
1111} from './ReactDOMControlledComponent' ;
1212
13+ import { enableDeprecatedFlareAPI } from 'shared/ReactFeatureFlags' ;
14+
1315// Used as a way to call batchedUpdates when we don't have a reference to
1416// the renderer. Such as when we're dispatching events or if third party
1517// libraries need to call batchedUpdates. Eventually, this API will go away when
@@ -87,8 +89,27 @@ export function discreteUpdates(fn, a, b, c, d) {
8789 }
8890}
8991
90- export function flushDiscreteUpdatesIfNeeded ( ) {
91- if ( ! isInsideEventHandler ) {
92+ let lastFlushedEventTimeStamp = 0 ;
93+ export function flushDiscreteUpdatesIfNeeded ( timeStamp : number ) {
94+ // event.timeStamp isn't overly reliable due to inconsistencies in
95+ // how different browsers have historically provided the time stamp.
96+ // Some browsers provide high-resolution time stamps for all events,
97+ // some provide low-resolution time stamps for all events. FF < 52
98+ // even mixes both time stamps together. Some browsers even report
99+ // negative time stamps or time stamps that are 0 (iOS9) in some cases.
100+ // Given we are only comparing two time stamps with equality (!==),
101+ // we are safe from the resolution differences. If the time stamp is 0
102+ // we bail-out of preventing the flush, which can affect semantics,
103+ // such as if an earlier flush removes or adds event listeners that
104+ // are fired in the subsequent flush. However, this is the same
105+ // behaviour as we had before this change, so the risks are low.
106+ if (
107+ ! isInsideEventHandler &&
108+ ( ! enableDeprecatedFlareAPI ||
109+ timeStamp === 0 ||
110+ lastFlushedEventTimeStamp !== timeStamp )
111+ ) {
112+ lastFlushedEventTimeStamp = timeStamp ;
92113 flushDiscreteUpdatesImpl ( ) ;
93114 }
94115}
0 commit comments