Updating component state after initialization

Just as a thought exercise, I wanted to know if there could be away to send updated props to a custom component after it has been initialized within a single run. Say, instead of raising a DuplicateWidgetID error when calling the same component with the same key within a single run, it would instead send the updated props to the frontend of the already initialized component. While I understand this is not possible with the currently exposed API over streamlit components, I was wondering if there could be some way to hook into the internal script runner, and modify this behaviour.

Such a behaviour could be quite useful in certain cases, like updating a component within a loop, which could be done asynchronously as well without blocking the execution of the rest of the script.

Just wanted to put this out there in hopes of sparking some discussion around this.

Cheers!

I don’t know if this is exactly like what you’re thinking of, but streamlit-folium supports something similar to this via a few arguments: center, zoom and feature_group_to_add. Any other argument that is passed to the map will cause the key to be updated, which will make the component get re-rendered. But if the feature_group_to_add argument is updated, the same map component will persist, and simply be updated.

Here is the python code streamlit-folium/streamlit_folium/__init__.py at master · randyzwitch/streamlit-folium · GitHub and here is the front-end code streamlit-folium/streamlit_folium/frontend/src/index.tsx at master · randyzwitch/streamlit-folium · GitHub

You can see an example of it in-use here: https://folium.streamlit.app/dynamic_map_vs_rerender

I’m not fully certain, but I don’t think this is doing that. In the example application, they use a button to modify the arguments to center, zoom and feature_group_to_add. In streamlit, when a button is clicked, the script is re-run, and in the new run, streamlit detects that the previous run had a component with that key, so it keeps that component and simply updates the component’s state without remounting it. On the other hand, say the component didn’t have a key, or streamlit found a key that didn’t exist in the previous run, it would then mount a new component with those arguments.

It is important to note here that the update reflects after a script rerun.

I’m talking about different arguments to the same component with the same key, within a single run.

Say, two different calls to streamlit_folio in the code, with the same arguments that build the the key, but different arguments for the others. The idea is that the first call placed the component in the UI with the original arguments, then the second call updates the very same component with new arguments, without throwing a DuplicateWidgetID error, or even creating a new component altogether. All within a single script run.

Ah, I see what you mean. Two different calls to st_folium but that have the same key, so they actually update the same underlying object. That is an interesting idea.

Something like this?

# creates the component initially
my_component(args1, key="foo")

# updates the already existing component, since it has the same key
my_component(args2, key="foo")

Yes, precisely.

Gotcha. That would be an interesting feature request to suggest on GitHub: Sign in to GitHub · GitHub