Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cursor jumping to end of input after switching to React.useElmish #320

Closed
bzuu-ic opened this issue Feb 25, 2021 · 2 comments
Closed

Cursor jumping to end of input after switching to React.useElmish #320

bzuu-ic opened this issue Feb 25, 2021 · 2 comments

Comments

@bzuu-ic
Copy link

bzuu-ic commented Feb 25, 2021

Issue

After refactoring parts of my application from using Elmish directly to using React components that use React.useElmish, I noticed various form inputs were misbehaving. Whenever you try to edit a form input by placing the cursor somewhere in the middle of a previously entered piece of text and start typing, the cursor jumps to the end of the field and you end up typing most of your characters in the wrong place.

The init, update and render functions are identical to the original code. Interestingly whenever I use prop.valueOrDefault instead of prop.value for keeping the input value in sync with the state, the jumping behaviour does not occur. Is this to be expected or perhaps a bug?

Reproduction steps

Given the following:

type State = { Name: string }

type Msg = ChangeName of string

let init () = { Name = "" }, Cmd.none

let update (msg: Msg) (state: State) =
    match msg with
    | ChangeName name -> { state with Name = name }, Cmd.none

let render (state: State) (dispatch: Msg -> unit) =
    Html.div [
        Html.input [ prop.className "input"
                     prop.value state.Name
                     prop.onChange (ChangeName >> dispatch)
                     prop.type'.text ]
        Html.text state.Name
    ]

These functions work fine, if used like this:

Program.mkProgram init update render
|> Program.withReactSynchronous "feliz-app"
|> Program.run

However it breaks if I wrap them in a ReactComponent with useElmish:

[<ReactComponent>]
let HelloWorld () =
    let (state, dispatch) = React.useElmish (init, update)
    render state dispatch

ReactDOM.render(
    HelloWorld(),
    document.getElementById "feliz-app"
)
@MangelMaxime
Copy link
Contributor

Hello @bzuu-ic ,

if you search for "Elmish cursor jump" you should find several discussions on this subject as it was a common question in the past.

The short answer is that using prop.valueOrDefault is probably the way to go when using Feliz.

You could potentially have the same behaviour observed with Elmish if you were using Program.withReactBatched

Main discussion about this situation in Elmish repo: elmish/react#12

@bzuu-ic
Copy link
Author

bzuu-ic commented Feb 25, 2021

Thanks @MangelMaxime good to know it is broader than Feliz. Other than it being counter intuitive, the workaround seems easy enough to implement.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants