Migrating to the default components
V1 and the event-driven components can live in the same process, but they do
not share a component tree. An app should use only sc.* components inside
its app function.
The mental model
V1:
import streamlit as st
count = st.session_state.get('count', 0)
if st.button('Increase'):
count += 1
st.session_state.count = count
st.text('Click count: {}'.format(count))
V3:
import streamlit_canary as sc
class State(sc.State):
count = sc.Property(0)
state = State()
def app():
with sc.Text('Click count: 0') as txt:
@state.count.on_change.partial(sc._self)
def _(cnt):
txt.text.set('Click count: {}'.format(cnt.get()))
with sc.Button('Increase') as btn:
@btn.on_click
def _():
state['count'] += 1
The differences:
- The app function runs once. There is no
if st.button(...)branch that runs on the next rerun. - State is explicit.
Statefields arePropertyobjects, not dictionary entries. - Widgets expose properties and signals. You attach a handler with
@widget.on_clickor@widget.value.on_changeinstead of reading a return value. - Updates are pushed. Changing
txt.textsends a patch; the browser replaces that text node.
A practical checklist
- Replace
st.session_statewith aStatesubclass. - Replace
st.button(...)plus anifbranch withsc.Button(...)plus@button.on_click. - Replace “read the widget’s return value” with
widget.value.get(). - Replace “write a widget’s value by assigning its return value” with
widget.value.set(...). - Move conditional rendering into a
Container(visible=...)or anExpander, rather than skipping code on a rerun. - Replace
st.rerun()with a state change. A rerun is neither needed nor available in the V3 runtime.
Things that do not translate one to one
- A V3 component is created once. If a widget should not exist at all, keep
it hidden with
visible=Falseinstead of not creating it. - Layout is built with context managers (
with sc.Row(): ...), not by assigning columns to variables. - Server-side code inside a handler runs on a worker thread. Keep handlers short, and do not block the event loop for long periods.