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"])

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",
)

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

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