Hi!
Love Streamlit ![]()
This little streamlit app demonstrates a problem that I have in the real app I’m building:
import time
import streamlit as st
# Handler for someone clicking the A checkbox
def A_changed():
st.session_state['countA_changed'] += 1
time.sleep(1)
# Handler for someone clicking the B checkbox
def B_changed():
st.session_state['countB_changed'] += 1
time.sleep(1)
# init the state first time through
if 'countA_changed' not in st.session_state:
st.session_state['countA_changed'] = 0
st.session_state['countB_changed'] = 0
# two checkboxes each with a handler
st.checkbox('A', key = 'A', on_change = A_changed)
st.checkbox('B', key = 'B', on_change = B_changed)
# display how many times each handler was called
st.write(st.session_state['countA_changed'], st.session_state['countB_changed'])
In the real app, a handler calls a function that querys a DB and takes a second or so to complete, so in the above handlers there is a little sleep to simulate that.
The problem is this: If you run this app and click on A, wait a second, and then click on B you see what you expect, a count of 1 for each handler, because the handler for A and B were both called once.
The same happens if you click on B, wait a second and then click on A.
But you’ll find that if you click on A and B and then B and A in quick succession then you get a count of 2 for A and 3 for B. The B handler gets called twice for the second event.
This is as simple as I could make it and still show the problem, but the real app is much more complex, and clicking on one checkbox might change the state of several others and then run the DB query… So I’ve got all sorts of workaround code that sneakily checks to make sure the checkbox value has really changed before proceeding but you can imagine it’s a bit messy.
Just wondering if this is a bug or if I’m doing something daft.
I did try putting the DB query in a separate thread and doing a filthy hack to rerun the script (because st.experimental_rerun didnt like being called from the thread) but that did not fix the issue!