Setting st.session_state variable not updated on next page load

Hi there,

When using a st.form the content of the form is updated correctly in the st.session_state.
However variables set by other code after clicking the submit button won’t show up in the st.session_state, but they will lag behind by 1 value. Is there any way to make sure values that are changed will show up when the page is reloaded instead of having a delayed change?

Code te reproduce

If you run the following code you will notice that the st.sesson_state.LastChanged value will be empty the first time after you click the submit button.

The second time it is clicked the old value will show up from when you first clicked it (keep note of the time).

from datetime import datetime
import streamlit as st

if 'LastChanged' not in st.session_state:
    st.session_state['LastChanged'] = ''

st.markdown("# Test with form submit button")

st.write("st.session_state")
st.write(st.session_state)

form = st.form("Settings")

label = "Test"
CurrentValue = 0
options = ["1", "2"]
index = 0
form.radio(label, options, index=index,
                 key=label, help=None, horizontal=False)

submitted = form.form_submit_button("Submit")

if submitted:
    st.session_state['LastChanged'] = str(datetime.now().strftime('%Y-%m-%d %H_%M_%S.%f'))


Seems like the only way to fix this is to do a rerun:

st.experimental_rerun()

Then everything works flawless.

In newer versions of streamlit (1.22.0), your code does not seem to demonstrate the “lagging behind” phenomenon. However, I am still experiencing it in my own code.

I am experiencing the same issue with version 1.26.0. Have you found a solution besides experimental_rerun()?

Another solution might be to use the callback/on_click param for st.form.

def onClick():
   st.session_state['LastChanged'] = str(datetime.now().strftime('%Y-%m-%d %H_%M_%S.%f'))

... (other code)

submitted = form.form_submit_button("Submit", on_click=onClick)

This changes it the moment you click the button.

Also a quick reminder that st.experimental_rerun() will soon be deprecated. So if you must, use st.rerun().

Best