-
Notifications
You must be signed in to change notification settings - Fork 80
Open
Description
SSCCE
https://ellie-app.com/vGfNrrxcb5ba1
module Main exposing (main)
import Browser
import Html exposing (Html)
import Html.Attributes
import Html.Events
import Html.Lazy
type alias Model =
{ text : String
, lazyText : String
}
initialModel : Model
initialModel =
{ text = ""
, lazyText = ""
}
type Msg
= GotText String
| GotLazyText String
update : Msg -> Model -> Model
update msg model =
case msg of
GotText text ->
{ model | text = String.filter Char.isDigit text }
GotLazyText text ->
{ model | lazyText = String.filter Char.isDigit text }
view : Model -> Html Msg
view model =
Html.div []
[ Html.p [] [ Html.text "These inputs only allow you to type digits. However, it doesn’t really work for the lazy one." ]
, Html.label []
[ Html.text "Regular: "
, viewText model.text |> Html.map GotText
]
, Html.hr [] []
, Html.label []
[ Html.text "Lazy: "
, Html.Lazy.lazy viewText model.lazyText |> Html.map GotLazyText
]
]
viewText : String -> Html String
viewText text =
Html.input
[ Html.Events.onInput identity
, Html.Attributes.value text
]
[]
main : Program () Model Msg
main =
Browser.sandbox
{ init = initialModel
, view = view
, update = update
}
The above code renders two inputs that are identical, except that one of them uses Html.Lazy.lazy
. As you type in them, non-digits are filtered away.
Html.Lazy.lazy
is not supposed to change behavior (only performance), but in this case it unfortunately does: Non-digits are not filterned away (until you type an actual digit).
Here’s what happens:
- The user types “a”.
- The browser updates
.value
of the input to"a"
. - The browser fires the
input
event. - The Elm
update
code filters"a"
to""
. view
is called.
For the regular input:
- No diff for
value
is detected compared to the previous virtual DOM (it is still the empty string). However,value
is special cased and is updated anyway. https://github.com/elm/virtual-dom/blob/1.0.3/src/Elm/Kernel/VirtualDom.js#L511 + https://github.com/elm/virtual-dom/blob/1.0.3/src/Elm/Kernel/VirtualDom.js#L927 - The result is that the user never sees “a” in the input field.
For the lazy input:
- Since the argument to
lazy
is unchanged (still the empty string), diffing is skipped. - The result is that the “a” that the browser put into the input field is left behind (even though the model says it should be the empty string).
Metadata
Metadata
Assignees
Labels
No labels