Session_state stored selectbox needs to be clicked twice

Running locally
Python 3.11.3
Streamlit 1.28.2

My code is this

selected_headline = st.sidebar.selectbox(
        "Select a Headline",
        options=st.session_state.headlines_list,
        index=st.session_state.selected_headline
    )
    st.session_state.selected_headline = st.session_state.headlines_list.index(selected_headline)

For some reason I need to click twice on the selectbox to actually be able to change it.
Small video showcasing it

I tried using an external function on_change and whatever it occurred to me but no luck.

My needs are having a selectbox on the sidebar that shares the same item selected across different pages, maybe there’s an easier way

Thank you.

Could you post a minimal reproducible code?

import streamlit as st

st.session_state.headlines_list = ['a', 'b', 'c']
if "selected_headline" not in st.session_state:
    st.session_state.selected_headline = 0

selected_headline = st.sidebar.selectbox(
        "Select a Headline",
        options=st.session_state.headlines_list,
        index=st.session_state.selected_headline
    )
st.session_state.selected_headline = st.session_state.headlines_list.index(selected_headline)

Here is a simpler solution: simply add a key to the selectbox, which then automatically adds an entry to st.session_state to track the selected item.

import streamlit as st

headlines = ["a", "b", "c"]


selected_headline = st.sidebar.selectbox(
    "Select a Headline",
    options=headlines,
    key="selected_headline",
)

st.write(selected_headline)
st.write(st.session_state["selected_headline"])
3 Likes

Hmm…

That works well in a single page, but does not work on a multi_page scenario, right?

I need the latter, simply having the exact same sidebar.selectbox with the same data and the same selected item when I change pages.

main.py

import streamlit as st
st.session_state.headlines = ["a", "b", "c"]

pages/first.py

import streamlit as st
selected_headline = st.sidebar.selectbox(
        "Select a Headline",
        options=st.session_state.headlines,
        key="selected_headline"
    )

pages/second.py

import streamlit as st
selected_headline = st.sidebar.selectbox(
        "Select a Headline",
        options=st.session_state.headlines,
        key="selected_headline"
    )

This is a better example of what I’m trying.

What’s the best way to achieve this?

Edited to include better example @blackary and thank you!

main.py

import streamlit as st

for k, v in st.session_state.items():
    st.session_state[k] = v

HEADLINES = ["a", "b", "c"]

Any other page

import streamlit as st
from main import HEADLINES

for key, val in st.session_state.items():
    st.session_state[key] = val


selected_headline = st.sidebar.selectbox(
    "Select a Headline",
    options=HEADLINES,
    key="selected_headline",
)
1 Like

Thank you for the code it works fine,

I’m not fully grasping it tho.

I also tested this:
main.py

import streamlit as st

HEADLINES = ["a", "b", "c"]

pages/first.py

import streamlit as st
from main import HEADLINES

for k, v in st.session_state.items():
    st.session_state[k] = v


selected_headline = st.sidebar.selectbox(
    "Select a Headline",
    options=HEADLINES,
    key="selected_headline",
)

pages/second.py

import streamlit as st
from main import HEADLINES

for k, v in st.session_state.items():
    st.session_state[k] = v


selected_headline = st.sidebar.selectbox(
    "Select a Headline",
    options=HEADLINES,
    key="selected_headline",
)

And it works fine, but I’m not certain if this is a good practice.

  • Should I have the same key for the component in the 2 pages considering it’s meant to be the same component?

The slightly-hacky part is

for k, v in st.session_state.items():
    st.session_state[k] = v

This makes sure that the session state is preserved across pages. We’re working on a more natural way to ensure that, but it’s the best option currently.

Using the same key on different pages is not a problem, and if you combine it with that session state trick above, it should keep the widgets in-sync with each other and with session state

2 Likes

Thank you so much!

I’d love to see the new solution, any ETA on that?

Not sure, but you can track progress here [Request for input] Keyed widget state persistence - discussion, possible fixes · Issue #6074 · streamlit/streamlit · GitHub

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