Why does changing the value of streamlit selectbox cause the entire page to refresh each time?

Iโ€™m building a Streamlit app to analyze Excel files. In the app, I have a selectbox where users can choose a column from the uploaded Excel file. However, each time I change the value of the selectbox to a different column, the entire page refreshes. This behavior is not desired as it disrupts the user experience. How can I modify the code to prevent the page from refreshing every time the selectbox value changes?

import pandas as pd
import helpers.script as script


@st.cache_data  # Cache the function based on month and year
def get_excel_path(month, year):
    return script.get_data(month, year)  # Call the original function

def read_excel_file(uploaded_file):
    """Reads the uploaded CSV file and returns a pandas DataFrame."""
    try:
        df = pd.read_excel(uploaded_file)
        return df
    except Exception as e:
        st.error(f"Error reading the file: {e}")
        return None

def display_unique_values(df, selected_column):
    """Displays the unique values in the selected column."""
    if selected_column:
        unique_values = df[selected_column].unique()
        st.write(f"Unique values in '{selected_column}':")
        st.dataframe(unique_values)


st.title("Excel File Analyzer")

year = st.number_input("Enter Year:", min_value=2024, max_value=None)
month = st.number_input("Enter Month (1-12)", min_value=1, max_value=12, step=1)

excel_path = None
df = None

if st.button("Generate Report"):
    excel_path = get_excel_path(month, year)

if excel_path is not None:
    df = read_excel_file(excel_path)    

if df is not None:
    # Get all column names
    column_options = list(df.columns)

    # Create a selectbox
    selected_column = st.selectbox("Select a column:", column_options, key="column_selectbox")

    display_unique_values(df.copy(), selected_column)  # Avoid modifying original DataFrame

st.stop()

Streamlit reruns the code from top to bottom if there are state changes or events triggered. It is what it is. Read the main concept of streamlit especially the data flow.

Fortunately, there is an upcoming streamlit version where we have the power to designate which function to rerun.

Hi @Ghulam_Mustafa :wave:

To add to @ferdyโ€™s comment and mitigate the โ€œrefreshโ€ effect when changing the selectbox value, you can leverage Streamlitโ€™s session state.

Implementing session state for your needs should be quite straightforward, but please let me know if you need any further assistance.

Best,
Charly

I used the session state, but It still did not work for me, I would really appreciate if you could look into it or tell me how setup the state

@Ghulam_Mustafa,

You should be able to address this issue through the following process:

First, youโ€™d need to initialize the Session State for the Selected Column. This is essential for maintaining the state across user interactions.

if 'selected_column' not in st.session_state:
    st.session_state.selected_column = None

Then, adjust the selectbox to use the Session State. This will prevent the entire page from refreshing when the selectbox value changes.

st.session_state.selected_column = st.selectbox(
    "Select a column:", 
    column_options, 
    key="column_selectbox", 
    index=column_options.index(st.session_state.selected_column) if st.session_state.selected_column in column_options else 0
)

Please share your progress with us! :slightly_smiling_face:

Best,
Charly