Strange Behavior in Custom Component StreamlitAntdComponents

I am using the menu component from the custom StreamlitAntdComponents(GitHub - nicedouble/StreamlitAntdComponents: A Streamlit component to display Antd-Design), and I’ve encountered two strange issues:

  1. When I click a menu option, the component automatically refreshes dozens of times. This behavior disappears when I remove all instances of Streamlit.setComponentValue from the menu component or I put the code outside the st.sidebar.
  2. When I execute st.rerun in Streamlit, this component first refreshes dozens of times, then it gets destroyed and rebuilt (remounted), leading to display errors.

Here is the code to reproduce the issue:

import streamlit as st
import streamlit_antd_components as sac

with st.sidebar:
    selected_module = sac.menu(
        [
            sac.MenuItem("Home", icon="house-fill"),

            sac.MenuItem(type="divider"),
            sac.MenuItem("Samples", icon="file-richtext-fill"),
        ],
        open_all=True,
        color="blue",
        index=2,
    )

st.write("Current selection:", selected_module)

if st.button("re run"):
    st.rerun()

After launching Streamlit, click on Home in the menu, and then click the button rerun. The menu component will be destroyed and rebuilt, resulting in the current selected value becoming Samples, while the component’s return value remains Home.
20240902160207_rec_

I’ve been trying to figure out the cause for a long time and haven’t been able to contact the author. Can anyone help?

I tried your code and didn’t find this issue. I’m not sure if it’s a streamlit version problem. Which version are you using?

I’m using streamlit==1.38.0, which version are you using? I’ve added a GIF to the post showing where the error occurs. Are you sure you can’t reproduce this issue?

Hi @yaosikai

Try the following code:

import streamlit as st
from streamlit import session_state as ss
import streamlit_antd_components as sac

if "idx" not in ss: ss.idx = -1
with st.sidebar:
    selected_module = sac.menu(
        [
            sac.MenuItem("Home", icon="house-fill"),
            sac.MenuItem(type="divider"),
            sac.MenuItem("Samples", icon="file-richtext-fill"),
        ],
        open_all=True,
        color="blue",
        index=ss.idx,
    )

st.write("Current selection:", selected_module)

if st.button("re run"): st.rerun()

Cheers

1 Like

I just understood what you mean. There is indeed an issue with ‘st. rerun()’. Normal component triggering does not exist. If you must use ‘st. rerun()’, I suggest you refer to Shawn_Pereira
Or use the following methods to solve this problem:

import streamlit as st
from streamlit import session_state as ss
import streamlit_antd_components as sac

def onChange_test():
    st.session_state.idx = st.session_state.test

if "idx" not in ss: ss.idx = 0
with st.sidebar:
    selected_module = sac.menu(
        [
            sac.MenuItem("Home", icon="house-fill"),
            sac.MenuItem(type="divider"),
            sac.MenuItem("Samples", icon="file-richtext-fill"),
        ],
        open_all=True,
        color="blue",
        index=ss.idx,
        key='test',
        return_index=True,  # 
        on_change=onChange_test  # 
    )
    st.write(st.session_state)

st.write("Current selection:", selected_module)

if st.button("re run"): st.rerun()

Thank you very much!

1 Like

Thank you very much!

@Shawn_Pereira @lkdd-ao
Thanks to both of you for your help, but I’ve thought of another question:

Official components can retain their state after executing a rerun, but custom components cannot. For the components I’ve developed myself, is there a way to preserve their state after a rerun?

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.