fable-compiler / fable-react

Fable bindings and helpers for React and React Native
MIT License
275 stars 66 forks source link

Add forwardRef hook #177

Open cmeeren opened 5 years ago

cmeeren commented 5 years ago

Material-UI often requires forwardRef if composing using functional components. I couldn't find the forwardRef hook in Fable.React. Would be great to have it!

nojaf commented 5 years ago

Are you sure? Don't you want https://github.com/fable-compiler/fable-react/blob/master/src/Fable.React.Hooks.fs#L43 in your case?

cmeeren commented 5 years ago

Based on the doc section I linked to, then yes, I'm pretty sure I need forwardRef, not useRef.

nojaf commented 5 years ago

My bad, you are correct.

This works for me in the repl

F#:

open Fable.Core.JsInterop
open Fable.React
open Fable.React.Props
open Browser.Types
open Fable.Core

[<Global("React.forwardRef")>]
let forwardRef<'Props,'Ref> (render:('Props -> 'Ref -> ReactElement)) : ReactElementType = jsNative
 // import "forwardRef" "react"

let EmailComponent =
    forwardRef<_, _> (fun _ ref -> 
        input [Ref ref]
    )

let App =
    FunctionComponent.Of(
        fun () -> 
            let emailRef = Hooks.useRef(JS.undefined<HTMLInputElement>)
            let onClick _ =
                emailRef.current.focus()

            div [] [
                ReactBindings.React.createElement(EmailComponent, {| ref = emailRef |}, [])
                button [OnClick onClick] [str "Click me to focus email"]
            ]

        , "App"
    )

mountById "app" (App())

html:

<!doctype html>
<html>
<head>
  <meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <script src="__HOST__/libs/react.production.min.js"></script>
  <script src="__HOST__/libs/react-dom.production.min.js"></script>
</head>
<body>
  <div id="app"></div>
</body>
</html>

So in your code you probably want something like:

let forwardRef<'Props,'Ref> (render:('Props -> 'Ref -> ReactElement)) : ReactElementType = import "forwardRef" "react"

@vbfox any thoughts on this?

Luiz-Monad commented 5 years ago

I added it, https://github.com/fable-compiler/fable-react/commit/fa43005e82490945e2a59beedf86054ae1e929a3 ( I had the same problem with MUI, you need fwRef for HoCs )

I guess the nuget package wasn't released yet, but it's merged.

cmeeren commented 5 years ago

Great! Any chance to get this deployed? I see it's been quite a while since it was comitted.

alfonsogarciacaro commented 5 years ago

Ups, seems I merged that right after coming back from holidays and forgot to release a new version, sorry! I'll do it right away 🚀