Repository: facebook/react
File: packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js (JavaScript)

Code before:
  instance.removeEventListener(type, listener, optionsOrUseCapture);
  return false;
}
function normalizeListenerOptions(
  opts: ?EventListenerOptionsOrUseCapture,
): string {
  if (opts == null) {
    return '0';
  }

  if (typeof opts === 'boolean') {
    return `c=${opts ? '1' : '0'}`;
  }

  return `c=${opts.capture ? '1' : '0'}&o=${opts.once ? '1' : '0'}&p=${opts.passive ? '1' : '0'}`;
}
function indexOfEventListener(
  eventListeners: Array<StoredEventListener>,
  type: string,
  listener: EventListener,
  optionsOrUseCapture: void | EventListenerOptionsOrUseCapture,
): number {
  const normalizedOptions = normalizeListenerOptions(optionsOrUseCapture);
  for (let i = 0; i < eventListeners.length; i++) {
    const item = eventListeners[i];
    if (
      item.type === type &&
      item.listener === listener &&
      normalizeListenerOptions(item.optionsOrUseCapture) === normalizedOptions
    ) {
      return i;
    }
  }
  return -1;
}
// $FlowFixMe[prop-missing]
FragmentInstance.prototype.dispatchEvent = function (
  this: FragmentInstanceType,
  event: Event,
): boolean {
  const parentHostFiber = getFragmentParentHostFiber(this._fragmentFiber);
  if (parentHostFiber === null) {
    return true;
  }
  const parentHostInstance =
    getInstanceFromHostFiber<Instance>(parentHostFiber);
  const eventListeners = this._eventListeners;
  if (
    (eventListeners !== null && eventListeners.length > 0) ||
    !event.bubbles
  ) {

Review comment (performance):
This doesn't really look like a hot path, but might be worth adding an early-return check for `eventListeners` size?

```
if (eventListeners.length === 0) {
  return -1;
}
```

Code after:
  instance.removeEventListener(type, listener, optionsOrUseCapture);
  return false;
}
function normalizeListenerOptions(
  opts: ?EventListenerOptionsOrUseCapture,
): string {
  if (opts == null) {
    return '0';
  }

  if (typeof opts === 'boolean') {
    return `c=${opts ? '1' : '0'}`;
  }

  return `c=${opts.capture ? '1' : '0'}&o=${opts.once ? '1' : '0'}&p=${opts.passive ? '1' : '0'}`;
}
function indexOfEventListener(
  eventListeners: Array<StoredEventListener>,
  type: string,
  listener: EventListener,
  optionsOrUseCapture: void | EventListenerOptionsOrUseCapture,
): number {
  if (eventListeners.length === 0) {
    return -1;
  }
  const normalizedOptions = normalizeListenerOptions(optionsOrUseCapture);
  for (let i = 0; i < eventListeners.length; i++) {
    const item = eventListeners[i];
    if (
      item.type === type &&
      item.listener === listener &&
      normalizeListenerOptions(item.optionsOrUseCapture) === normalizedOptions
    ) {
      return i;
    }
  }
  return -1;
}
// $FlowFixMe[prop-missing]
FragmentInstance.prototype.dispatchEvent = function (
  this: FragmentInstanceType,
  event: Event,
): boolean {
  const parentHostFiber = getFragmentParentHostFiber(this._fragmentFiber);
  if (parentHostFiber === null) {
    return true;
  }
  const parentHostInstance =
    getInstanceFromHostFiber<Instance>(parentHostFiber);
  const eventListeners = this._eventListeners;
  if (