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

Code before:

  function mountVirtualChildrenRecursively(
    firstChild: Fiber,
    lastChild: null | Fiber, // non-inclusive
    traceNearestHostComponentUpdate: boolean,
    virtualLevel: number, // the nth level of virtual instances
  ): void {
    // Iterate over siblings rather than recursing.
    // This reduces the chance of stack overflow for wide trees (e.g. lists with many items).
    let fiber: Fiber | null = firstChild;
    let previousVirtualInstance: null | VirtualInstance = null;
    let previousVirtualInstanceFirstFiber: Fiber = firstChild;
    while (fiber !== null && fiber !== lastChild) {
      let level = 0;
      if (fiber._debugInfo) {
        for (let i = 0; i < fiber._debugInfo.length; i++) {
          const debugEntry = fiber._debugInfo[i];
          if (debugEntry.awaited) {
            // Async Info
            const asyncInfo: ReactAsyncInfo = (debugEntry: any);
            if (level === virtualLevel) {
              // Track any async info between the previous virtual instance up until to this
              // instance and add it to the parent. This can add the same set multiple times
              // so we assume insertSuspendedBy dedupes.
              insertSuspendedBy(asyncInfo);
            }
            continue;
          }
          if (typeof debugEntry.name !== 'string') {
            // Not a Component. Some other Debug Info.
            continue;
          }
          // Scan up until the next Component to see if this component changed environment.
          const componentInfo: ReactComponentInfo = (debugEntry: any);
          const secondaryEnv = getSecondaryEnvironmentName(fiber._debugInfo, i);
          if (componentInfo.env != null) {
            knownEnvironmentNames.add(componentInfo.env);
          }
          if (secondaryEnv !== null) {
            knownEnvironmentNames.add(secondaryEnv);
          }
          if (shouldFilterVirtual(componentInfo, secondaryEnv)) {
            // Skip.
            continue;
          }
          if (level === virtualLevel) {
            if (
              previousVirtualInstance === null ||
              // Consecutive children with the same debug entry as a parent gets
              // treated as if they share the same virtual instance.
              previousVirtualInstance.data !== debugEntry

Review comment (bug):
Does this use the correct index?

```suggestion
          const debugEntry = debugInfo[j];
```


Code after:
  }

  function trackDebugInfoFromUsedThenables(fiber: Fiber): void {
    // If a Fiber called use() in DEV mode then we may have collected _debugThenableState on
    // the dependencies. If so, then this will contain the thenables passed to use().
    // These won't have their debug info picked up by fiber._debugInfo since that just
    // contains things suspending the children. We have to collect use() separately.
    const dependencies = fiber.dependencies;
    if (dependencies == null) {
      return;
    }
    const thenableState = dependencies._debugThenableState;
    if (thenableState == null) {
      return;
    }
    // In DEV the thenableState is an inner object.
    const usedThenables: any = thenableState.thenables || thenableState;
    if (!Array.isArray(usedThenables)) {
      return;
    }
    for (let i = 0; i < usedThenables.length; i++) {
      const thenable: Thenable<mixed> = usedThenables[i];
      const debugInfo = thenable._debugInfo;
      if (debugInfo) {
        for (let j = 0; j < debugInfo.length; j++) {
          const debugEntry = debugInfo[i];
          if (debugEntry.awaited) {
            const asyncInfo: ReactAsyncInfo = (debugEntry: any);
            insertSuspendedBy(asyncInfo);
          }
        }
      }
    }
  }

  function mountVirtualChildrenRecursively(
    firstChild: Fiber,
    lastChild: null | Fiber, // non-inclusive
    traceNearestHostComponentUpdate: boolean,
    virtualLevel: number, // the nth level of virtual instances
  ): void {
    // Iterate over siblings rather than recursing.
    // This reduces the chance of stack overflow for wide trees (e.g. lists with many items).
    let fiber: Fiber | null = firstChild;
    let previousVirtualInstance: null | VirtualInstance = null;
    let previousVirtualInstanceFirstFiber: Fiber = firstChild;
    while (fiber !== null && fiber !== lastChild) {
      let level = 0;
      if (fiber._debugInfo) {
        for (let i = 0; i < fiber._debugInfo.length; i++) {
          const debugEntry = fiber._debugInfo[i];