Skip to content

[BUG] Dash 3 Components as Props #3234

Closed
Closed

Description

@BSd3v

When components are props are unmounted, they dont unmount properly

Activity

  1. BSd3v commented on Mar 21, 2025

    @BSd3v
    ContributorAuthor

    Run this example:

    
    
    import dash_mantine_components as dmc
    from dash import Output, Input, html, callback, Dash, ctx, _dash_renderer
    from dash.exceptions import PreventUpdate
    from dash_iconify import DashIconify
    
    # this is optional when using dash >3.0.0
    _dash_renderer._set_react_version("18.2.0")
    
    app = Dash(__name__, external_stylesheets=dmc.styles.ALL)
    
    app.layout = dmc.MantineProvider(
        [
            dmc.NotificationProvider(),
            html.Div(id="notify-container"),
            dmc.Group(
                children=[
                    dmc.Button(
                        "Load Data",
                        id="show-notification",
                    ),
                    dmc.Button(
                        "Update",
                        id="update-notification",
                    ),
                ],
            ),
        ],
    )
    
    
    @callback(
        Output("notify-container", "children"),
        Input("show-notification", "n_clicks"),
        Input("update-notification", "n_clicks"),
        prevent_initial_call=True,
    )
    def notify(nc1, nc2):
        if not ctx.triggered:
            raise PreventUpdate
        else:
            button_id = ctx.triggered_id
            if "show" in button_id:
                return dmc.Notification(
                    id="my-notification",
                    title="Process initiated",
                    message="The process has started.",
                    loading=True,
                    color="orange",
                    action="show",
                    autoClose=False,
                )
            else:
                return dmc.Notification(
                    id="my-notification",
                    title="Data loaded",
                    message="Notification closing in 2 seconds",
                    color="green",
                    loading=False,
                    action="update",
                    autoClose=2000,
                    icon=DashIconify(icon="akar-icons:circle-check"),
                )
    app.clientside_callback(
        """(c) => {
            if (c) {
                setTimeout(() => dash_clientside.set_props('notify-container', {children: []}, 2000))
            }
        }""",
        Input('notify-container', 'children')
    )
    
    
    if __name__ == "__main__":
        app.run(debug=True)
    

    click show and then try to update, and you will encounter the issue. It freezes everything for me. I believe the issue comes from the Icon which is set as React.ReactNode

  2. BSd3v commented on Mar 23, 2025

    @BSd3v
    ContributorAuthor

    From what I can tell, it happens when removing a parent element that contains one of these node components.

    The icon in notification is a react node which is dash iconify.

    And to clarify, the issue points to the selector that listens to redux for state changes.

  3. CNFeffery commented on Mar 23, 2025

    @CNFeffery
    Contributor

    If it's regarding component-type parameters, I haven't been able to reproduce such issues in the fac (>=0.4.0rc1) adapted for dash 3.0.

    dash                           3.0.0
    feffery_antd_components        0.4.0rc1

    import dash
    from dash import html
    import feffery_antd_components as fac
    from feffery_dash_utils.style_utils import style
    from dash.dependencies import Input, Output, State
    
    app = dash.Dash(__name__)
    
    app.layout = html.Div(
        [
            fac.AntdButton("button-demo", id="button-demo"),
            html.Div(
                fac.AntdButton(icon=fac.AntdIcon(icon="antd-eye")), id="button-container"
            ),
        ],
        style=style(padding=50),
    )
    
    
    @app.callback(
        Output("button-container", "children"),
        Input("button-demo", "nClicks"),
        State("button-container", "children"),
        prevent_initial_call=True,
    )
    def update_icon(nClicks, icon):
        return (
            fac.AntdButton(icon=fac.AntdIcon(icon="antd-eye-invisible"))
            if icon["props"]["icon"]["props"]["icon"] == "antd-eye"
            else fac.AntdButton(icon=fac.AntdIcon(icon="antd-eye"))
        )
    
    
    if __name__ == "__main__":
        app.run(debug=True)

    Image

  4. CNFeffery commented on Mar 23, 2025

    @CNFeffery
    Contributor

    From what I can tell, it happens when removing a parent element that contains one of these node components.

    The icon in notification is a react node which is dash iconify.

    I've updated the test examples. Not sure if it's similar to the callback update scenario you described.

  5. BSd3v commented on Mar 23, 2025

    @BSd3v
    ContributorAuthor

    @CNFeffery it would be like removing the button-container from the dash tree.

    For example, if I remove the icon from the component in my callback for the notification, it works. But add the icon and it breaks.

  6. self-assigned this
    on Mar 24, 2025
  7. added theissue type on Mar 24, 2025
  8. added
    bugsomething broken
    dash-3.0Going in dash-3.0 release.
    P1needed for current cycle
    on Mar 24, 2025
  9. BSd3v commented on Mar 31, 2025

    @BSd3v
    ContributorAuthor

    I believe that my PR may address this: #3248

  10. BSd3v commented on Apr 1, 2025

    @BSd3v
    ContributorAuthor
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

P1needed for current cyclebugsomething brokendash-3.0Going in dash-3.0 release.

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions