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

Explore if we can shadow equalsButFunctions or FunctionComponent from Fable.React #26

Open
MangelMaxime opened this issue May 23, 2019 · 1 comment

Comments

@MangelMaxime
Copy link
Member

Description

If you have a component like:

let private colorCircle =
    FunctionComponent.Of(fun (props : {| Rank : int
                                         Color : Color.Marker.ColorReferences
                                         OnPick : int -> unit |}) ->
        Button.button [ Button.OnClick(fun _ -> props.OnPick props.Rank) ]
            [ str props.Color.Name ]
    , "ColorSelector"
    , equalsButFunctions
    )

Then if you have an HMR call triggered the component instance in the DOM will not be re-render and still have a reference to the old OnPick callback. OnPick callback is created using dispatch for example ChangeColor >> dispatch.

The reason, is we are ignoring functions when determining if we need to redraw it.

We had the same problem with LazyView coming from Elmish and wrote our own version of it source

@MangelMaxime
Copy link
Member Author

It seems like this code should do the job:

module HMR =

    let hot = HMR.``module``.hot

    /// Normal structural F# comparison, but ignores top-level functions (e.g. Elmish dispatch).
    /// Can be used e.g. with the `FunctionComponent.Of` `memoizeWith` parameter.
    let equalsButFunctions (x: 'a) (y: 'a) =
        #if DEBUG
            if hot.status() = HMR.Status.Apply then
                false
            else
                Fable.React.Helpers.equalsButFunctions x y
        #else
            Fable.React.Helpers.equalsButFunctions
        #endif

More thinking need to be done around the way to shadow the API and also if we need an inline call somewhere to make zero impact on production bundle size

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

No branches or pull requests

1 participant