sydsutton / FS.FluentUI

V9 of Microsoft's FluentUI library, built for F# in the style of Feliz.
https://github.com/sydsutton/FS.FluentUI
MIT License
70 stars 4 forks source link

dispatchToast crashes when bundled #9

Closed otytlandsvik closed 1 month ago

otytlandsvik commented 1 month ago

Hi, thanks for your contributions, we use these bindings extensively! We're having some trouble with Toasts at the moment:

Calls to dispatchToast seems to crash the app when called, only if the app is built and previewed with vite. The error message output by react is a "Minified React error #31":

Objects are not valid as a React child (found: object with keys {timeout, politeness, intent, toastId}). If you meant to render a collection of children, use an array instead.

It seems the generated js does not output a valid Toast ReactElement, but instead attempts to render the DispatchToastOptions as an object.

To reproduce

This issue is only present when built, running the project normally without the build argument passed to vite allows toasts to work as intended.

Thanks. Let me know if you need any more info or are unable to reproduce.

sydsutton commented 1 month ago

Hey @otytlandsvik , thanks for the first legit issue in regards to a specific component! Sorry to hear that-- the Toast component was definitely one of the more complicated to get working (or almost working, I guess). I'll look into it and keep you posted. Feel free to look around the project; maybe you can spot the issue before I can.

sydsutton commented 1 month ago

@otytlandsvik Although I'm having a hard time reproducing it, I'm assuming it has something to do with tree shaking when Vite is building. I'm thinking that maybe if I use more variables/ functions in order to create the dispatchToast method, then it won't be as affected by tree shaking. Just a theory, though. I'll keep trying to reproduce it. Any thoughts? image

otytlandsvik commented 1 month ago

Hi, I implemented your proposal and it did not seem to resolve the issue unfortunately.

I also published a minimal example (with your proposal) here, hopefully you can also reproduce my issue using this repo. The build target Preview bundles and serves the project and crashes on my end, like described.

otytlandsvik commented 1 month ago

I think I managed to solve it!

By the looks of things, the use of your utility JSTuple.from2Args is problematic in this case. The compiled js code looks something like this:

    const dispatchToast = (tupledArg) => {
        const element = tupledArg[0];
        const options = tupledArg[1];
        const options_1 = createObj(options);
        const args = [element, options_1];
        controller.dispatchToast(args[0], args[1]);
    };

...and when vite performs its bundling magic, it turns into:

        (props_2) => {
            let args_1;
            const tupledArg = props_2;
            controller.dispatchToast(
                ((args_1 = [tupledArg[0], createObj(tupledArg[1])]),
                args_1[0],
                args_1[1]),
            );
        },

Instead emitting the arguments directly into the function like this seems to work:

        let dispatchToast (element, options) =
            let options = !!options |> createObj |> unbox<DispatchToastOptions>
            emitJsExpr (element, options) "$0, $1"
            |> controller.dispatchToast

I'll create a PR in a moment.

sydsutton commented 1 month ago

This is exactly why I made this project public-- so that people smarter than me can solve the issues that I can't quite figure out yet. 😁 Thanks for the repo branch and the PR! I'll push a new version with the change soon.