Skip to content

Commit

Permalink
use microtick outside of events (#3879)
Browse files Browse the repository at this point in the history
Fixes #3775
Fixes #3724

When we are in events we need setTimeout to deal with how events bubble, we want the events to complete before we start our rendering process. This however isn't needed when we are dealing with internal updates coming from effects/...

Co-authored-by: andrewiggins <[email protected]>
  • Loading branch information
JoviDeCroock and andrewiggins authored Feb 3, 2023
1 parent ef708b9 commit 6e2e952
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 3 deletions.
15 changes: 14 additions & 1 deletion src/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { assign } from './util';
import { diff, commitRoot } from './diff/index';
import options from './options';
import { Fragment } from './create-element';
import { inEvent } from './diff/props';

/**
* Base Component class. Provides `setState()` and `forceUpdate()`, which
Expand Down Expand Up @@ -183,6 +184,18 @@ let rerenderQueue = [];

let prevDebounce;

const microTick =
typeof Promise == 'function'
? Promise.prototype.then.bind(Promise.resolve())
: setTimeout;
function defer(cb) {
if (inEvent) {
setTimeout(cb);
} else {
microTick(cb);
}
}

/**
* Enqueue a rerender of a component
* @param {import('./internal').Component} c The component to rerender
Expand All @@ -196,7 +209,7 @@ export function enqueueRender(c) {
prevDebounce !== options.debounceRendering
) {
prevDebounce = options.debounceRendering;
(prevDebounce || setTimeout)(process);
(prevDebounce || defer)(process);
}
}

Expand Down
18 changes: 16 additions & 2 deletions src/diff/props.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,15 +141,29 @@ export function setProperty(dom, name, value, oldValue, isSvg) {
}
}

export let inEvent = false;

/**
* Proxy an event to hooked event handlers
* @param {Event} e The event object from the browser
* @private
*/
function eventProxy(e) {
return this._listeners[e.type + false](options.event ? options.event(e) : e);
inEvent = true;
try {
return this._listeners[e.type + false](
options.event ? options.event(e) : e
);
} finally {
inEvent = false;
}
}

function eventProxyCapture(e) {
return this._listeners[e.type + true](options.event ? options.event(e) : e);
inEvent = true;
try {
return this._listeners[e.type + true](options.event ? options.event(e) : e);
} finally {
inEvent = false;
}
}

0 comments on commit 6e2e952

Please sign in to comment.