Force evaluation of a Lazy view

I am using Html.Lazy to render some elements. This is because there is no need for these elements to be re-rendered when many other components of the model change.

However, there are circumstances where I want these elements re-rendered even though their values in the model is unchanged.

Example: Say I have an input box called Title.

  • When the user enters a new valid title, the model value is updated (on blur in my case) and the view corresponds to what the user typed.
  • When the user enters a new invalid title, the model is not updated, but the view still corresponds to what the user typed (because of Html.Lazy.lazy). This is when I need a re-render so that the value matches the unchanged model value (and not what the user typed).

How can I achieve this?

Thank you.

The DOM will always be updated if there is anything that needs to be changed. I think it sounds like you should be adding the value attribute to your input field so that you can control the value of the field. If you do that, then it should update the DOM when appropriate.

Maybe someone can be more helpful if you post some example code of what you’re currently doing.

Hmm true, here’s an example of the issue: https://ellie-app.com/676BXKpnpXDa1

One way to solve it would be to wrap the string in a custom type like type Foo = Foo String.
Because lazy uses reference equality, it will then count as a new value and rerender, even if it’s equal to the old one.

Rewrote the example with type Foo = Foo String: https://ellie-app.com/676Jd33nHcta1

Oh, thanks for the example – I better understand what you’re talking about now.

Here’s what comes to mind for me as a way to control the laziness: https://ellie-app.com/677X4PqDvPTa1 Basically I’m keeping both the typed and the validated strings in the model, and using them both as arguments to lazy, even though only the validated one is actually used by the textInput function. (And I think something like this is clearer and more understandable than using a wrapper type that depends on a trick using reference equality.)

That doesn’t work as well as Herteby’s example. Try pressing SPACE twice, and in your example one space will be shown in lazy input.

1 Like

Thank you @Herteby. That seems clever. Just to understand it better, does reference equality mean that even though Foo "hello" is the same value as Foo "hello" in value, when a new Foo "hello" is created, it refers to a different object?

Yup, I assume it’s just using === in JS.

"hello" === "hello" -> true
{a:"hello"} === {a:"hello"} -> false

Normally this is something to watch out for, because it can make lazy not work and cause unnecessary rerenders (and I guess doing a structural comparison like how Elm’s == works would be too slow). But I guess it has it’s uses too.

Appreciate the explanation. Thank you.

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.