diff --git a/ppx/reason_react_ppx.ml b/ppx/reason_react_ppx.ml index 9646da10c..b66fa424a 100644 --- a/ppx/reason_react_ppx.ml +++ b/ppx/reason_react_ppx.ml @@ -653,11 +653,6 @@ let jsxMapper = (Invalid_argument "Key cannot be accessed inside of a component. Don't worry - you \ can always key a component from its parent!") - | Pexp_fun (Labelled "ref", _, _, _) | Pexp_fun (Optional "ref", _, _, _) -> - raise - (Invalid_argument - "Ref cannot be passed as a normal prop. Please use `forwardRef` \ - API instead.") | Pexp_fun ( ((Optional label | Labelled label) as arg), default, diff --git a/ppx/test/component.t/input.re b/ppx/test/component.t/input.re index 7fdccd901..3c9839e68 100644 --- a/ppx/test/component.t/input.re +++ b/ppx/test/component.t/input.re @@ -41,6 +41,13 @@ module Forward_Ref = { }); }; +module Ref_as_prop = { + [@react.component] + let make = (~children, ~ref) => { + ; + }; +}; + module Onclick_handler_button = { [@react.component] let make = (~name, ~isDisabled=?) => { diff --git a/ppx/test/component.t/run.t b/ppx/test/component.t/run.t index aa9583ce1..22e4bcbf5 100644 --- a/ppx/test/component.t/run.t +++ b/ppx/test/component.t/run.t @@ -68,6 +68,27 @@ We need to output ML syntax here, otherwise refmt could not parse it. make ~buttonRef:(Props ## buttonRef) ~children:(Props ## children) in Output$Forward_Ref) end + module Ref_as_prop = + struct + external makeProps : + children:'children -> + ref:'ref -> + ?key:string -> unit -> < children: 'children ;ref: 'ref > Js.t + = ""[@@mel.obj ] + let make = + ((fun ~children -> + ((fun ~ref -> + ReactDOM.jsx "button" + (((ReactDOM.domProps)[@merlin.hide ]) ~children ~ref + ~className:"FancyButton" ())) + [@warning "-16"])) + [@warning "-16"]) + let make = + let Output$Ref_as_prop + (Props : < children: 'children ;ref: 'ref > Js.t) = + make ~ref:(Props ## ref) ~children:(Props ## children) in + Output$Ref_as_prop + end module Onclick_handler_button = struct external makeProps : diff --git a/test/Ref__test.re b/test/Ref__test.re new file mode 100644 index 000000000..223a5f348 --- /dev/null +++ b/test/Ref__test.re @@ -0,0 +1,35 @@ +open Jest; +open Expect; + +module Button_with_ref = { + [@react.component] + let make = (~children, ~ref) => { + ; + }; +}; + +let getByRole = (role, container) => { + ReactTestingLibrary.getByRole(~matcher=`Str(role), container); +}; + +[@mel.get] external innerHTML: Dom.element => string = "innerHTML"; + +describe("ref", () => { + test("can be passed as prop to a component", () => { + let domRef = React.createRef(); + let container = + ReactTestingLibrary.render( + + {React.string("Click me")} + , + ); + let button = getByRole("FancyButton", container); + expect(button->innerHTML)->toBe("Click me"); + let content = + switch (Js.Nullable.toOption(domRef.current)) { + | Some(element) => element->innerHTML + | None => failwith("No element found") + }; + expect(content)->toBe("Click me"); + }) +});