Skip to content

Custom components are remounted on every prop update (Gradio ≥ 6.20) #13818

Description

@pablo-rerun

Describe the bug

Found a bug where custom component are failing to load for us on the gradio-rerun component for any verison of gradio> 6.20 https://github.com/rerun-io/gradio-rerun-viewer

with an agent came up with the following fix

js/core/src/MountCustomComponent.svelte


<script lang="ts">
	import { untrack } from "svelte";

	let { node, children, ...rest } = $props();

	let component = $derived(await node.component);
@@ -20,14 +22,22 @@
		const _props = node.props.props;
		const _runtime = runtime;

		const mounted = _runtime.mount(component.default, {
			target: el,
			props: {
				shared_props: _shared_props,
				props: _props,
				children
			}
		});
		// The custom component runs in its own Svelte runtime instance, so
		// its synchronous init cannot reset *this* runtime's tracking
		// context. Without untrack(), every core `$state` read the component
		// makes while mounting (e.g. the `Gradio` class copying
		// shared_props/props) becomes a dependency of this effect, and every
		// later prop update unmounts and remounts the component.
		const mounted = untrack(() =>
			_runtime.mount(component.default, {
				target: el,
				props: {
					shared_props: _shared_props,
					props: _props,
					children
				}
			})
		);

		return () => {
			_runtime.unmount(mounted);

validated this fixed things for me

closet issue #13131 and the fix looks like #13817

but it doesn't look like this is a fix for this particular issue we have

Have you searched existing issues? 🔎

  • I have searched and found no existing issues

Reproduction

pip install "gradio==6.26.0" build
gradio cc create RemountProbe --template SimpleTextbox --no-configure-metadata --directory remountprobe

In remountprobe/frontend/Index.svelte, after const gradio = new Gradio(...), add:

onMount(() => { console.log("PROBE mounted"); return () => console.log("PROBE unmounted"); });
cd remountprobe && gradio cc build --no-generate-docs && cd .. && pip install -e remountprobe
import time
import gradio as gr
from gradio_remountprobe import RemountProbe

def stream():
    for i in range(5):
        time.sleep(0.3)
        yield f"value-{i}"

with gr.Blocks() as demo:
    out = RemountProbe(label="probe", value="init")
    gr.Button("Go").click(stream, outputs=out)

demo.launch()

Click Go. Expected: one PROBE mounted. Actual: 15 unmounted/mounted pairs; the component's DOM is recreated each time.

Screenshot

Image

Logs

System Info

gradio 6.26.0, gradio_client 2.6.1, Python 3.11, macOS, Chrome 152
Same MountCustomComponent.svelte on 6.9.0 through 6.26.0 and main

Severity

Blocking usage of gradio

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions