I have a text input, and I've managed to debounce input. However, my keypress listener won't wait for text input events to flush before processing the enter key which would end edits without getting the latest value in the uncontrolled component.
Since I'm in webpack, React...
is undefined so I can't just React.createRef()
The current source code shows the function exists https://github.com/fable-compiler/fable-react/blob/e904add886bab45003c074cd2b06b8834fddf65b/src/Fable.React.Helpers.fs#L366
However it doesn't resolve/compile. paket.lock
shows Fable.React 4.1.3, Fable.Elmish.React 2.1.
createRef
is available only since version 5.x something so you need to update to latest version. To be sure, I encourage you to upgrade to the latest version at the time of writing 5.2.3
.
This means you will need to upgrade your application to Fable.Core v3, you can read more about it here .
When done you can use createRef
like that:
open Fable.React
open Fable.React.Props
type MapComponent(initProps) =
inherit Fable.React.Component<MapComponentProps, obj>(initProps)
let mapRef : IRefHook<Browser.Types.HTMLDivElement option> = createRef None
override this.render() =
div [ RefValue mapRef ]
[ str "..." ]
As it turned out, for what I needed, the ref wasn't necessary, however I did get one going.
type IReactRef =
inherit Browser.Element
[<Emit("React.createRef")>]
let createRef(): IReactRef = jsNative
type TextInputProps =
{ Ident: string
Delay: int
AddedAttributes: IHTMLProp list
DefaultValue: string option
OnChange: (string -> unit)
OnEscape: (unit -> unit) option
OnEnter: (string -> unit) option
}
type TextInputState = InputState
let textInputDelayDefault = 500
type TextInputComponent(props) =
inherit React.Component<TextInputProps, TextInputState>(props)
let mutable textInput: obj = null
let debouncer = Eventing.Debouncer<string>.Create props.Ident props.Delay
do
textInput <- react.createRef()
base.setInitState InputState
member __.TextInput: IReactRef option =
textInput
|> Option.ofObj
|> Option.map unbox
// provide cancel edit extension point (Escape doesn't fire keypress)
member this.OnKeyUp(e: React.KeyboardEvent) =
if e.key = "Escape" then
match this.props.OnEscape with
| Some f ->
e.preventDefault()
f()
| None -> ()
// provide finish edit extension point
member this.OnKeyPress(e: React.KeyboardEvent) =
let value =
e
|> unbox
|> Eventing.getTargetValue
if e.key = "Enter" then
this.props.OnEnter
|> Option.iter (fun f ->
e.preventDefault()
debouncer.Clear()
// send the current value in case the onChange did not send the current value due to debouncing
f value)
override this.render() =
let r =
input [ yield R.Props.Ref(unbox textInput)
yield R.Props.OnKeyPress this.OnKeyPress
yield R.Props.OnKeyUp this.OnKeyUp
yield Eventing.onDebChange debouncer this.props.OnChange
yield R.Props.DefaultValue(this.props.DefaultValue |> Option.defaultValue "")
yield! this.props.AddedAttributes ]
r
let inline textInputComponent props = Fable.Helpers.React.ofType<TextInputComponent, _, _> props []
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.