elmish / hmr

Hot Module Replacement for Elmish apps
https://elmish.github.io/hmr
Other
28 stars 9 forks source link

HMR and lazyView #8

Closed toburger closed 5 years ago

toburger commented 5 years ago

Description

Just wanted to continue the discussion from https://github.com/elmish/react/issues/22 and the somehow related issue from https://github.com/elmish/hmr/issues/6.

Repro code

Usage of both packages Fable.Elmish.HMR and Fable.Elmish.React combined result in subparts of the view not updated when using HMR and one of the lazyX functions from Elmish.React.

Expected and actual results

Expected:

One of two behaviors:

Actual:

Certain parts of the view aren't updated and it is hard for the consumer of the two libs to figure out why views aren't updated anymore.

MangelMaxime commented 5 years ago

Do you have additional ideas or comments on the ideas we exposed at the end of the discussion?

toburger commented 5 years ago

No better idea other than your proposal of shadowing the lazyX functions, sorry...

MangelMaxime commented 5 years ago

@et1975

What do you think of this proposition (copied from https://github.com/elmish/react/issues/22#issuecomment-374988783):

I believe the easiest way is to use the HMR.Common shadowing.

Module code would be something like:

module HMR.Common

let inline lazyView x = x

let inline lazyViewWith cmp x = x

// Etc.

User code:

#if HMR
open HMR.Common
#endif

And also adding the HMRconstant to webpack config.

MangelMaxime commented 5 years ago

I think I know how to fix lazyView usage with HMR support. But then it's possible that react stateful can have some special behavior on some circumstance. I will need to explore my idea and make some tests before being able to share the code in the open.

et1975 commented 5 years ago

The shadowing should happen by default IMHO, there shouldn't be a need to discover correct solution. Just opening the Elmish.HMR should bring in the shadows for lazyView,Program.toNavigable, etc. The order of module openings is a concern, but if you get it right in the template - you've covered 80% of cases, and the last 20% can find the solution in the docs.

MangelMaxime commented 5 years ago

Yes I think because Fable is compiling the source code we can use #if DEBUG in the lib code directly and not ask the user to do it for us.

Like that he just need to do:

open Elmish.Common
open Elmish.HMR

let view = 
   lazyView ....

And so here lazyView will comes from Elmish.HMR.lazyView in Debug mode and from Elmish.Common.lazyView in production code.

MangelMaxime commented 5 years ago

This has been fixed by #11

Use the following open statement and you will have it working.

open Elmish.React
open Elmish.HMR

The lazyView content is forced to refresh on HMR trigger but otherwise still behave as a lazyView.

Demo:

2018-11-09 21 40 44