over_react_annotation_required_prop

Severity: AnalysisErrorSeverity.INFO

Maturity: stable

Since 1.0.0

View the Project on GitHub workiva/over_react

ALWAYS provide a value for late required props, either directly or by forwarding props.

Please see the documentation for null safety and required props for more information on required prop validation, which, in addition to this lint, also includes runtime asserts.

Those docs also note exceptions to this rule under the Disabling required prop validation for certain props section, and include instructions for handling those. One common case where this doesn't apply are "wrapper" components that render another component and set some of its props within its render.

Examples:

Given the following component with the required prop user:

mixin UserChipProps on UiProps {
  late User user;
  bool? isSelected;
}

UiFactory<UserChipProps> UserChip = uiFunction((props) {
  // ...
}, _$UserChipConfig);

Then whenever UserChip is render, that required prop must always be set by the consumer.

GOOD:

    (UserChip()..user = user)()

BAD:

   UserChip()()
// ^^^^^^^^^^
// warning: Missing required late prop 'user' from 'UserChipProps'.
// (over_react_late_required_prop)

and, that code will also throw a runtime error when asserts are enabled:

Uncaught Error: RequiredPropsError: Required prop `user` is missing.
   at Object.throw_ [as throw]
   at _$$UserChipProps$JsMap.new.validateRequiredProps

Prop forwarding

GOOD:

mixin CustomUserChipPropsMixin on UiProps {
  String? color;
}

class CustomUserChipProps = UiProps with UserChipProps, CustomUserChipPropsMixin;

UiFactory<CustomUserChipProps> CustomUserChip = uiFunction((props) {
  final color = props.color;
  
  return (UserChip()
    // Required props are correctly forwarded here by the wrapper component 
    ..addProps(props.getPropsToForward(exclude: {CustomUserChipPropsMixin})
    ..style = {
      if (color != null) 'border': '2px solid $color', 
      ...?props.style,
    } 
  )();
}, _$CustomUserChipConfig);

BAD:

UiFactory<CustomUserChipProps> CustomUserChip = uiFunction((props) {
  final color = props.color;
  
  // Required props are not forwarded, so we get:
  //   warning: Missing required late prop 'user' from 'UserChipProps'.
  //   (over_react_late_required_prop)
  return (UserChip()
    ..style = {
      if (color != null) 'border': '2px solid $color', 
      ...?props.style,
    } 
  )();
}, _$CustomUserChipConfig);