getForwardingTargets function
List
getForwardingTargets(
- dynamic reactInstance, {
- int expectedTargetCount = 1,
- 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;
}