nicedouble / StreamlitAntdComponents

A Streamlit component to display Antd-Design
https://nicedouble-streamlitantdcomponentsdemo-app-middmy.streamlit.app/
MIT License
440 stars 29 forks source link

Setting component state does not set its value #26

Open Puumanamana opened 1 year ago

Puumanamana commented 1 year ago

Hello,

I noticed a general issue with sac components. All components I have tested (tabs, chips, segmented) are reset each time the code is reran (the session state is preserved but it doesn't seem to update the widget when reran). I was able to circumvent this issue by fetching the value in the session state and setting it with index=, but it makes the components blink each time it is set that way (probably because a new component is created each time). Do you have a good way to make it more fluid?

This is probably related in some way to #25.

Here's a small example:

import streamlit as st
import streamlit_antd_components as sac

st.title("Issue #25")

st.session_state["toggle"] = True
st.toggle("toggle", key="toggle")
# Toggle set to True

st.session_state["switch"] = True
sac.switch(label='label', key="switch")
# Switch not set

For some reason, setting the switch with value here works fine and it doesn't blink, but with more complex component (such as the example given in #25), it's happening.

Thanks!

nicedouble commented 11 months ago

Hi, In verson 0.2.5,i add the feature that change component value or index by set session state.

I was able to circumvent this issue by fetching the value in the session state and setting it with index=, but it makes the components blink each time it is set that way

you can retry you issue.On my test, the blink disappear.

Puumanamana commented 11 months ago

Thank you! It works for the switch when I set index={state}. However, I still notice issues with sac.menu. Here's an example, where I try to update the URL parameters based on what is selected in the menu:

import streamlit as st
import streamlit_antd_components as sac

def update_url():
    """Update the URL to reflect the currently selected menu item."""
    if "menu" in st.session_state:
        st.experimental_set_query_params(menu=st.session_state.menu)

st.write("Session state={}, URL state={}".format(
    st.session_state.get('menu'),
    st.experimental_get_query_params().get('menu', [None])[0]
))

index = ['home', 'products'].index(st.session_state.get("menu", "home"))

sac.menu(
    [sac.MenuItem('home'),
     sac.MenuItem('products')],
    format_func='title', open_all=True, key="menu", on_change=update_url,
    index=index
)

I think this might be due to the fact that when the index= argument changes, a new widget is created, which causes the blinking.

CHerSun commented 11 months ago

Query params are marked experimental for a reason. There's an issue in Streamlit repo, that a full 3rd party component redraw is being triggered on any change in url (including params). Also, setting query params forces a full redraw in some strange manner, I've seen that previously too (I think there's a closed issue in SAC repo with that discussion; updated: no, it was in some other project, cba to search for that now).

st.session_state should allow you to change selected item flicker-less with the latest version nicedouble has released just recently exactly with that feature.

Puumanamana commented 11 months ago

I didn't observe this issue for all widgets, just for custom ones (e.g., the option-menu widget). Or maybe it's just a matter of widget complexity. I'm not familiar with all of streamlit backend, so I thought it was worth mentioning it in case it was something that could be fixed at the StreamlitAntdComponents level. I was also wondering if this was due to the fact that you can't set the state of sac.menu before it's instantiated (contrary to regular streamlit widgets, as shown in the code above), and I was wondering if that would solve anything.