Radio Button Displays Previous Selection After Reload

Hello everyone,

I’m experiencing an issue with my Streamlit app. I have the following code:

import streamlit as st

if st.button("reload"):
    st.cache_data.clear()
    st.rerun()

radio_state = st.radio("Radio", ["A", "B", "C"])
st.write(radio_state)

Here’s what happens:

  • I select the radio button “C” and the screen displays “C” as expected.
  • Then, when I click the “reload” button, the radio button appears to still be in the “C” position, but the text displayed by st.write(radio_state) shows “A”.

Question:
Why does the displayed value revert to “A” after reloading, even though the UI still seems to highlight “C”? Has anyone encountered this issue or know what might be causing it?

Hey @shirotabi ,

Try setting index = 0. Full code will be - radio_state = st.radio("Radio", ["A", "B", "C"], index = 0) . This will set the default value of radio button to first value in value list.

Hope this helps.

I think that is a bug in streamlit. Anyway, it looks like you are abusing rerun(). You probably want this instead:

st.button("reload", on_click=st.cache_data.clear)

PS. An old bug, indeed.

1 Like

Hi @Dhruv4
Thank you for your suggestion! I appreciate your time and effort in helping me. I tried setting index=0, but unfortunately, it did not solve the issue in my case. The radio button always resets to the first option when I press the reload button, which is not the behavior I was looking for.

Still, I really appreciate your response. Thank you for your help!

Best,

Hi @Goyo

Thank you for your insightful response! Your suggestion to use st.button("reload", on_click=st.cache_data.clear) was really helpful, and I appreciate the reference to the GitHub issue—it provided great context.

In my case, I still need to use rerun() for my project, so this solution is not a perfect fit. However, your response helped me better understand the behavior and possible alternatives.

Thanks again for your help and for sharing the GitHub link!

Best,

After experimenting a bit, I realized that the issue was related to how rerun() interacts with the order of code execution. Initially, my code looked like this:

if 'radio_selection' not in st.session_state:
    st.session_state.radio_selection = "A"  # default value

if st.button("reload", on_click=st.cache_data.clear):
    st.write("Cache cleared")
    st.rerun()

radio_state = st.radio("Radio", ["A", "B", "C"], index=0)
st.session_state.radio_selection = radio_state

st.write(radio_state)

As I mentioned before, this caused the radio button to visually stay on the selected option (like “C”), but after clicking reload, the displayed value reverted to “A.”

First Attempt:

I thought this was because rerun() was processed before the radio button selection. So, I moved the reload button to the end of the script:

if 'radio_selection' not in st.session_state:
    st.session_state.radio_selection = "A"  # default value

radio_state = st.radio("Radio", ["A", "B", "C"], index=0)
st.session_state.radio_selection = radio_state

st.write(radio_state)

if st.button("reload", on_click=st.cache_data.clear):
    st.write("Cache cleared")
    st.rerun()

This actually prevented the issue. However, it forced me to place the reload button at the bottom, which isn’t flexible in terms of UI layout since the component placement depends on execution order.

Final Solution:

To solve this, I decided to use st.container() to separate the layout from the execution flow. Here’s the final working code:

class LayoutDesign:
    def __init__(self):
        self.reload_button = st.container()
        self.radio_button = st.container()
        self.preview = st.container()

class Controller:
    def reload_button(self, container):
        if container.button("reload"):
            st.write("Cache cleared")
            st.cache_data.clear()
            st.rerun()
    
    def radio_button(self, container):
        radio_state = container.radio("Radio", ["A", "B", "C"], index=0)
        st.session_state["radio_selection"] = radio_state

    def preview(self, container):
        container.write(st.session_state["radio_selection"])

if "radio_selection" not in st.session_state:
    st.session_state["radio_selection"] = "A"

layout = LayoutDesign()
controller = Controller()
controller.radio_button(layout.radio_button)
controller.preview(layout.preview)
controller.reload_button(layout.reload_button)

By using st.container(), I could control the layout freely without worrying about the execution order affecting the UI.

2 Likes

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