Skip to content

Commit 1ab7253

Browse files
committed
[reactjs] add support for ref argument inside of React.forwardRef type applications
1 parent 511b50e commit 1ab7253

File tree

1 file changed

+10
-5
lines changed

1 file changed

+10
-5
lines changed

jscomp/syntax/reactjs_jsx_ppx.cppo.ml

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -477,9 +477,10 @@ let jsxMapper () =
477477
recursivelyTransformNamedArgsForMake mapper expression ((arg, default, pattern, alias, pattern.ppat_loc, type_) :: list)
478478
| Pexp_fun (Nolabel, _, { ppat_desc = (Ppat_construct ({txt = Lident "()"}, _) | Ppat_any)}, _expression) ->
479479
(list, None)
480-
| Pexp_fun (Nolabel, _, { ppat_desc = Ppat_var ({txt})}, _expression) ->
480+
| Pexp_fun (Nolabel, _, { ppat_desc = Ppat_var ({txt}) | Ppat_constraint ({ ppat_desc = Ppat_var ({txt})}, _)}, _expression) ->
481481
(list, Some txt)
482-
482+
| Pexp_fun (Nolabel, _, pattern, _expression) ->
483+
Location.raise_errorf ~loc:pattern.ppat_loc "ReasonReact: react.component refs only support plain arguments and type annotations."
483484
| _ -> (list, None)
484485
in
485486

@@ -618,6 +619,7 @@ let jsxMapper () =
618619
spelunkForFunExpression expression
619620
in
620621
let modifiedBinding binding =
622+
let hasApplication = ref(false) in
621623
let wrapExpressionWithBinding expressionFn expression =
622624
Vb.mk
623625
~loc:bindingLoc
@@ -641,14 +643,16 @@ let jsxMapper () =
641643
(* let make = (~prop) => ... *)
642644
| {
643645
pexp_desc = Pexp_fun ((Labelled(_) | Optional(_)), _default, _pattern, _internalExpression)
644-
} -> ((fun a -> a), false, unerasableIgnoreExp expression)
646+
} -> ((fun a -> a), false, unerasableIgnoreExp expression)
645647
(* let make = (prop) => ... *)
646648
| {
647649
pexp_desc = Pexp_fun (_nolabel, _default, _pattern, _internalExpression);
648650
pexp_loc
649651
} ->
650-
Location.raise_errorf ~loc:pexp_loc
651-
"Make sure to use labeled arguments for props, if your component doesn't take any props use () or _ instead of a name as your argument"
652+
if (hasApplication.contents) then
653+
((fun a -> a), false, unerasableIgnoreExp expression)
654+
else
655+
Location.raise_errorf ~loc:pattern.ppat_loc "ReasonReact: props need to be labelled arguments.\n If you are working with refs be sure to wrap with React.forwardRef.\n If your component doesn't have any props use () or _ instead of a name."
652656
(* let make = {let foo = bar in (~prop) => ...} *)
653657
| {
654658
pexp_desc = Pexp_let (recursive, vbs, internalExpression)
@@ -658,6 +662,7 @@ let jsxMapper () =
658662
(wrap, hasUnit, {expression with pexp_desc = Pexp_let (recursive, vbs, exp)})
659663
(* let make = React.forwardRef((~prop) => ...) *)
660664
| { pexp_desc = Pexp_apply (wrapperExpression, [(Nolabel, internalExpression)]) } ->
665+
let () = hasApplication := true in
661666
let (_, hasUnit, exp) = spelunkForFunExpression internalExpression in
662667
((fun exp -> Exp.apply wrapperExpression [(nolabel, exp)]), hasUnit, exp)
663668
| {

0 commit comments

Comments
 (0)