getForwardingTargets function

List getForwardingTargets(
  1. dynamic reactInstance, {
  2. int expectedTargetCount = 1,
  3. dynamic shallowRendered = false,
})

Return the components to which props have been forwarded.

Identified using the forwardedPropBeacon prop key.

Implementation

List getForwardingTargets(reactInstance, {int expectedTargetCount = 1, shallowRendered = false}) {
  if (!forwardedPropBeacon.startsWith('data-')) {
    throw Exception('forwardedPropBeacon must begin with "data-" so that is a valid HTML attribute.');
  }

  List forwardingTargets;

  if (shallowRendered) {
    forwardingTargets = [];

    final descendantsToProcess = Queue<dynamic>()..add(reactInstance);
    while (descendantsToProcess.isNotEmpty) {
      final descendant = descendantsToProcess.removeFirst();

      if (descendant is Iterable) {
        descendantsToProcess.addAll(descendant);
        continue;
      }

      // Some props may be of type Function, and will produce interop errors if passed into isValidElement
      if (descendant is! Function && isValidElement(descendant)) {
        final props = getProps(descendant);
        if (props.containsKey(forwardedPropBeacon)) {
          forwardingTargets.add(descendant);
        }

        Iterable<dynamic> propValues;
        try {
          propValues = props.values;
        } catch (_) {
          // IE 11 doesn't support Object.values
          propValues = props.keys.map((key) => props[key]);
        }
        // Most importantly, this includes children, but also includes other props that could contain React content.
        descendantsToProcess.addAll(propValues);
      }
    }
  } else {
    // Filter out non-DOM components (e.g., React.DOM.Button uses composite components to render)
    forwardingTargets = findDescendantsWithProp(reactInstance, forwardedPropBeacon);
    forwardingTargets = forwardingTargets.where(react_test_utils.isDOMComponent).toList();
  }

  if (forwardingTargets.length != expectedTargetCount) {
    throw StateError('Unexpected number of forwarding targets: ${forwardingTargets.length};'
        ' make sure a component with addUnconsumedProps/addUnconsumedDomProps is being rendered.');
  }
  return forwardingTargets;
}