Created
May 31, 2020 11:40
-
-
Save kerams/cc1c56ee323718d82b55b0c262f6c23f to your computer and use it in GitHub Desktop.
Reusable debouncer hook for F#/React/Fable based on Feliz.UseElmish
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// depends on https://www.nuget.org/packages/Feliz.UseElmish | |
module Debouncer = | |
type private DebounceState<'a> = { | |
Value: 'a | |
OnDone: 'a -> unit | |
Delay: int } | |
type private Msg<'a> = | |
| ValueChanged of 'a | |
| Debounced of 'a | |
let private init value onDone delay = | |
{ Value = value; OnDone = onDone; Delay = delay }, [] | |
let private update msg state = | |
match msg with | |
| Debounced thenValue -> | |
if state.Value = thenValue then | |
state.OnDone thenValue | |
state, [] | |
| ValueChanged value -> | |
let a = async { | |
do! Async.Sleep state.Delay; | |
return Debounced value } | |
{ state with Value = value }, Cmd.OfAsyncImmediate.result a | |
let useDebouncer value onDone delay = | |
let current, dispatch = Feliz.React.useElmish (init value onDone delay, update, [||]) | |
current.Value, (ValueChanged >> dispatch) | |
// Usage | |
// Use `onChange` to inform the debouncer about every change in the underlying input field | |
// When the value hasn't changed in 300ms, the debouncer will pass the current value to | |
// the function provided to it, dispatching a `SearchTermChanged` message to the parent | |
// component in this case. The actual debouncing is thus completely hidden away from the user. | |
let search = Feliz.React.functionComponent (fun (x: {| dispatch: Msg -> unit |}) -> | |
let currentValue, onChange = Debouncer.useDebouncer "" (SearchTermChanged >> x.dispatch) 300 | |
div [] [ | |
input [ Type "text"; Value currentValue; OnChange (fun x -> onChange x.Value) ] | |
]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment