diff --git a/compiler/syntax/src/jsx_v4.ml b/compiler/syntax/src/jsx_v4.ml index 795655fbb8..872e7ac282 100644 --- a/compiler/syntax/src/jsx_v4.ml +++ b/compiler/syntax/src/jsx_v4.ml @@ -1216,6 +1216,22 @@ let map_binding ~config ~empty_loc ~pstr_loc ~file_name ~rec_flag binding = let make_new_binding ~loc ~full_module_name binding = let props_pattern = match binding.pvb_expr with + | {pexp_desc = Pexp_apply (wrapper_expr, [(Nolabel, func_expr)])} + when is_forward_ref wrapper_expr -> + (* Case when using React.forwardRef *) + let rec check_invalid_forward_ref expr = + match expr.pexp_desc with + | Pexp_fun ((Labelled _ | Optional _), _, _, _, _) -> + Location.raise_errorf ~loc:expr.pexp_loc + "Components using React.forwardRef cannot use \ + @react.componentWithProps. Please use @react.component \ + instead." + | Pexp_fun (Nolabel, _, _, body, _) -> + check_invalid_forward_ref body + | _ -> () + in + check_invalid_forward_ref func_expr; + Pat.var {txt = "props"; loc} | { pexp_desc = Pexp_fun (_, _, {ppat_desc = Ppat_constraint (_, typ)}, _, _); diff --git a/tests/build_tests/super_errors/expected/react_component_with_props.res.expected b/tests/build_tests/super_errors/expected/react_component_with_props.res.expected new file mode 100644 index 0000000000..66083eef22 --- /dev/null +++ b/tests/build_tests/super_errors/expected/react_component_with_props.res.expected @@ -0,0 +1,15 @@ + + We've found a bug for you! + /.../fixtures/react_component_with_props.res:4:5-13:10 + + 2 │ @react.componentWithProps + 3 │ let make = React.forwardRef(( + 4 │ ~className=?, + 5 │  ~children, + . │ ... + 12 │  children + 13 │   + 14 │ ) + 15 │ } + + Components using React.forwardRef cannot use @react.componentWithProps. Please use @react.component instead. \ No newline at end of file diff --git a/tests/build_tests/super_errors/fixtures/react_component_with_props.res b/tests/build_tests/super_errors/fixtures/react_component_with_props.res new file mode 100644 index 0000000000..29ca3b301b --- /dev/null +++ b/tests/build_tests/super_errors/fixtures/react_component_with_props.res @@ -0,0 +1,15 @@ +module V4C7 = { + @react.componentWithProps + let make = React.forwardRef(( + ~className=?, + ~children, + ref: Js.Nullable.t, + ) => +
+ Belt.Option.map(React.Ref.domRef)} + /> + children +
+ ) +} diff --git a/tests/syntax_tests/data/ppx/react/sharedPropsWithProps.res b/tests/syntax_tests/data/ppx/react/sharedPropsWithProps.res index 1598adf762..00d382bc92 100644 --- a/tests/syntax_tests/data/ppx/react/sharedPropsWithProps.res +++ b/tests/syntax_tests/data/ppx/react/sharedPropsWithProps.res @@ -90,4 +90,4 @@ module V4A6 = { | #off => React.string("off") } } -} \ No newline at end of file +}