Proxy 在 React SyntheticEvent 中的应用

react SyntheticEvent

近日在开发 React 应用中发现 SyntheticEvent 是一个 Proxy 对象,比较好奇 SyntheticEvent 这里怎么用到了 Proxy,于是查看下 React 的源码。

/** Proxying after everything set on SyntheticEvent
 * to resolve Proxy issue on some WebKit browsers
 * in which some Event properties are set to undefined (GH#10010)
 */
if (__DEV__) {
  const isProxySupported =
    typeof Proxy === 'function' &&
    // https://github.com/facebook/react/issues/12011
    !Object.isSealed(new Proxy({}, {}));

  if (isProxySupported) {
    /*eslint-disable no-func-assign */
    SyntheticEvent = new Proxy(SyntheticEvent, {
      construct: function(target, args) {
        return this.apply(target, Object.create(target.prototype), args);
      },
      apply: function(constructor, that, args) {
        return new Proxy(constructor.apply(that, args), {
          set: function(target, prop, value) {
            if (
              prop !== 'isPersistent' &&
              !target.constructor.Interface.hasOwnProperty(prop) &&
              shouldBeReleasedProperties.indexOf(prop) === -1
            ) {
              warning(
                didWarnForAddedNewProperty || target.isPersistent(),
                "This synthetic event is reused for performance reasons. If you're " +
                  "seeing this, you're adding a new property in the synthetic event object. " +
                  'The property is never released. See ' +
                  'https://fb.me/react-event-pooling for more information.',
              );
              didWarnForAddedNewProperty = true;
            }
            target[prop] = value;
            return true;
          },
        });
      },
    });
    /*eslint-enable no-func-assign */
  }
}

可以看到 Proxy 被用来修改 SyntheticEvent 的 set 操作,当尝试向 SyntheticEvent 对象添加新的属性时,会弹出 warning。