memo<TProps extends UiProps> function

UiFactory<TProps> memo<TProps extends UiProps>(
  1. UiFactory<TProps> factory, {
  2. bool areEqual(
    1. TProps prevProps,
    2. TProps nextProps
    )?,
  3. String? displayName,
})

A higher order component for function components that behaves similar to the way React.PureComponent does for class-based components.

If your function component renders the same result given the same props, you can wrap it in a call to memo for a performance boost in some cases by memoizing the result. This means that React will skip rendering the component, and reuse the last rendered result.

NOTE: This should only be used to wrap function components.

import 'package:over_react/over_react.dart';

UiFactory<UiProps> MemoExample = memo(uiFunction(
  (props) {
    // render using props
  },
  _$MemoExampleConfig, // ignore: undefined_identifier
));

memo only affects props changes. If your function component wrapped in memo has a useState or useContext Hook in its implementation, it will still rerender when state or context change.

By default it will only shallowly compare complex objects in the props map using propsOrStateMapsEqual. If you want control over the comparison, you can also provide a custom comparison function to the areEqual argument as shown in the example below.

import 'package:over_react/over_react.dart';

UiFactory<MemoWithComparisonProps> MemoWithComparison = memo(uiFunction(
  (props) {
    // render using props
  },
  _$MemoWithComparisonConfig, // ignore: undefined_identifier
), areEqual: (prevProps, nextProps) {
  // Do some custom comparison logic to return a bool based on prevProps / nextProps
});

This method only exists as a performance optimization.

Do not rely on it to “prevent” a render, as this can lead to bugs.

See: reactjs.org/docs/react-api.html#reactmemo.

Implementation

UiFactory<TProps> memo<TProps extends UiProps>(UiFactory<TProps> factory,
    {bool Function(TProps prevProps, TProps nextProps)? areEqual,
    String? displayName}) {
  enforceFunctionComponent(factory().componentFactory);

  ReactComponentFactoryProxy hoc;
  if (areEqual != null) {
    bool wrapProps(Map prevProps, Map nextProps) {
      final tPrevProps = factory(prevProps);
      final tNextProps = factory(nextProps);
      return areEqual(tPrevProps, tNextProps);
    }

    hoc = react_interop.memo2(factory().componentFactory!, areEqual: wrapProps);
  } else {
    hoc = react_interop.memo2(factory().componentFactory!, areEqual: propsOrStateMapsEqual);
  }

  setComponentTypeMeta(hoc.type as Object,
      isHoc: true, parentType: factory().componentFactory!.type);

  TProps forwardedFactory([Map? props]) {
    return factory(props)..componentFactory = hoc;
  }

  return forwardedFactory;
}