Repository: facebook/react
File: packages/react-devtools-shared/src/backend/agent.js (JavaScript)

Code before:
    } else {
      renderer.deletePath(type, id, hookID, path);
    }
  };

  getInstanceAndStyle({
    id,
    rendererID,
  }: ElementAndRendererID): InstanceAndStyle | null {
    const renderer = this._rendererInterfaces[rendererID];
    if (renderer == null) {
      console.warn(`Invalid renderer id "${rendererID}"`);
      return null;
    }
    return renderer.getInstanceAndStyle(id);
  }

  getIDForNode(node: Object): number | null {
    const renderers = [];
    for (const rendererID in this._rendererInterfaces) {
      const renderer = ((this._rendererInterfaces[
        (rendererID: any)
      ]: any): RendererInterface);
      renderers.push(renderer);
    }
    const rendererInterface = getBestMatchingRendererInterface(renderers, node);
    if (rendererInterface != null) {
      return rendererInterface.getFiberIDForNative(node, true);
    }
    return null;
  }

  getBackendVersion = () => {
    const version = process.env.DEVTOOLS_VERSION;
    if (version) {
      this._bridge.send('backendVersion', version);
    }
  };

  getBridgeProtocol = () => {
    this._bridge.send('bridgeProtocol', currentBridgeProtocol);
  };

  getProfilingData = ({rendererID}: {|rendererID: RendererID|}) => {
    const renderer = this._rendererInterfaces[rendererID];
    if (renderer == null) {
      console.warn(`Invalid renderer id "${rendererID}"`);
    }

    this._bridge.send('profilingData', renderer.getProfilingData());
  };

Review comment (suggestion):
This probably should be in the `backend/agent` file instead of the utils because you're using two for loops right now and if you put the code from `getBestMatchingRendererInterface` into the agent you would only need one

ex. 

```js
let renderer = this._rendererInterfaces[0];
for (const rendererID in this._rendererInterfaces) {
  const currentRenderer = ...;
  const fiber = currentRenderer.getFiberForNative(node, false);
  if (fiber !== null && fiber.stateNode === node) {
   renderer = currentRenderer;
    break;
  }
  ...
}
...
```

Code after:
  };

  getInstanceAndStyle({
    id,
    rendererID,
  }: ElementAndRendererID): InstanceAndStyle | null {
    const renderer = this._rendererInterfaces[rendererID];
    if (renderer == null) {
      console.warn(`Invalid renderer id "${rendererID}"`);
      return null;
    }
    return renderer.getInstanceAndStyle(id);
  }

  getBestMatchingRendererInterface(node: Object): RendererInterface | null {
    let bestMatch = null;
    for (const rendererID in this._rendererInterfaces) {
      const renderer = ((this._rendererInterfaces[
        (rendererID: any)
      ]: any): RendererInterface);
      const fiber = renderer.getFiberForNative(node);
      if (fiber !== null) {
        // check if fiber.stateNode is matching the original hostInstance
        if (fiber.stateNode === node) {
          return renderer;
        } else if (bestMatch === null) {
          bestMatch = renderer;
        }
      }
    }
    // if an exact match is not found, return the first valid renderer as fallback
    return bestMatch;
  }

  getIDForNode(node: Object): number | null {
    const rendererInterface = this.getBestMatchingRendererInterface(node);
    if (rendererInterface != null) {
      try {
        return rendererInterface.getFiberIDForNative(node, true);
      } catch (error) {
        // Some old React versions might throw if they can't find a match.
        // If so we should ignore it...
      }
    }
    return null;
  }

  getBackendVersion = () => {
    const version = process.env.DEVTOOLS_VERSION;
    if (version) {
      this._bridge.send('backendVersion', version);