fix: Avoid mutating Event properties that are supposed to be getters (#33536)

* Avoid mutating Event properties that are supposed to be getters

React's synthetic Event objects have mutable `target` and `currentTarget` properties. These are an incorrect emulation of the corresponding DOM Event properties, which are _getters_ and cannot be assigned-to. AntD's input handling attempts to assign to these getters, which fails in Preact because it uses native Event objects. The solution is to replace the simple property assignments with property definitions, which is likely smaller anyway due to the existing use of `Object.create()` to construct a prototypal facade of Event objects.

* Apply suggestions from code review

* Apply suggestions from code review

Co-authored-by: afc163 <afc163@gmail.com>
This commit is contained in:
Jason Miller 2022-01-04 09:41:12 -05:00 committed by GitHub
parent cf5eac1a8c
commit 36a5485870
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -83,9 +83,6 @@ export function resolveOnChange<E extends HTMLInputElement | HTMLTextAreaElement
let event = e;
if (e.type === 'click') {
// click clear icon
event = Object.create(e);
// Clone a new target for event.
// Avoid the following usage, the setQuery method gets the original value.
//
@ -100,8 +97,11 @@ export function resolveOnChange<E extends HTMLInputElement | HTMLTextAreaElement
const currentTarget = target.cloneNode(true) as E;
event.target = currentTarget;
event.currentTarget = currentTarget;
// click clear icon
event = Object.create(e, {
target: { value: currentTarget },
currentTarget: { value: currentTarget },
});
currentTarget.value = '';
onChange(event as React.ChangeEvent<E>);
@ -110,9 +110,10 @@ export function resolveOnChange<E extends HTMLInputElement | HTMLTextAreaElement
// Trigger by composition event, this means we need force change the input value
if (targetValue !== undefined) {
event = Object.create(e);
event.target = target;
event.currentTarget = target;
event = Object.create(e, {
target: { value: target },
currentTarget: { value: target },
});
target.value = targetValue;
onChange(event as React.ChangeEvent<E>);