您如何在Suave Fable中创建Ref?

时间:2019-05-07 21:44:28

标签: suave fable-f#

我有一个文本输入,并且设法消除了输入的反跳。但是,我的按键侦听器在处理回车键之前不会等待文本输入事件刷新,因为回车键会终止编辑而不会在不受控制的组件中获取最新值。

由于我在webpack中,React...是未定义的,所以我不能只是React.createRef()当前源代码显示该功能存在https://github.com/fable-compiler/fable-react/blob/e904add886bab45003c074cd2b06b8834fddf65b/src/Fable.React.Helpers.fs#L366

但是它不能解析/编译。 paket.lock显示Fable.React 4.1.3,Fable.Elmish.React 2.1。

2 个答案:

答案 0 :(得分:0)

createRef仅从5.x版本开始可用,因此您需要更新到最新版本。可以肯定的是,我鼓励您在编写5.2.3时升级到最新版本。

这意味着您需要将应用程序升级到Fable.Core v3,您可以here了解更多信息。

完成后,您可以像这样使用createRef

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 "..." ]

答案 1 :(得分:0)

事实证明,对于我所需要的,裁判不是必需的,但是我确实做到了。

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 []