preparePropsChangeset function

dynamic preparePropsChangeset(
  1. ReactElement element,
  2. Map? newProps, [
  3. Iterable? newChildren
])

Returns a new JS map with the specified props and children changes, properly prepared for consumption by React JS methods such as cloneElement, setProps, and other methods that accept changesets of props to be merged into existing props.

Handles both Dart and JS React components, returning the appropriate props structure for each type:

  • For non-react.Component2 Dart components, existing props are read from InteropProps.internal, which are then merged with the new newProps and saved in a new InteropProps with the expected ReactDartComponentInternal structure.
  • For react.Component2 Dart components, newProps is passed through ReactDartComponentFactoryProxy2.generateExtendedJsProps and then passed to React JS, which will merge the props normally.
  • Children are likewise copied and potentially overwritten with newChildren as expected.
  • For JS components, a JS copy of newProps is returned, since React will merge the props without any special handling. If these values might contain event handlers

Implementation

dynamic preparePropsChangeset(ReactElement element, Map? newProps, [Iterable? newChildren]) {
  final type = element.type;
  final dartComponentVersion = ReactDartComponentVersion.fromType(type); // ignore: invalid_use_of_protected_member

  // react.Component
  if (dartComponentVersion == ReactDartComponentVersion.component) { // ignore: invalid_use_of_protected_member
    Map oldExtendedProps = _getInternal(element).props;

    Map extendedProps = Map.from(oldExtendedProps);
    if (newProps != null) {
      extendedProps.addAll(newProps);
    }

    // ignore: deprecated_member_use
    return ReactDartComponentFactoryProxy.generateExtendedJsProps(extendedProps, newChildren ?? extendedProps['children']);
  }

  if (newProps == null) {
    // Only pre-Component2 Dart components need changesets if props aren't null,
    // since the new children need to be stored on the props.internal.
    // Otherwise, we can pass `null` straight through to React.
    return null;
  }

  // react.Component2
  if (dartComponentVersion == ReactDartComponentVersion.component2) { // ignore: invalid_use_of_protected_member
    return ReactDartComponentFactoryProxy2.generateExtendedJsProps(newProps);
  }

  // DOM component
  if (type is String) {
    // Convert props for DOM components so that style Maps and event handlers
    // originating from Dart are properly converted.
    final convertedProps = Map.from(newProps);
    ReactDomComponentFactoryProxy.convertProps(convertedProps);
    return jsifyAndAllowInterop(convertedProps);
  }

  // JS Component
  return jsifyAndAllowInterop(newProps);
}