[8] streamlit button 이용한 데이터 삭제
들어가며
이번 챕터에서는 streamlit button을 이용해서 등록되어 있는 포켓몬을 삭제하는 기능을 구현해보겠습니다.
streamlit button
streamlit button 문서: https://docs.streamlit.io/library/api-reference/widgets/st.button
streamlit button은 버튼 UI를 간단하게 구현할 수 있고, 눌렀을 때 동작을 조건문으로 작성할 수 있습니다.
삭제 버튼 UI 추가
포켓몬 속성 텍스트 밑에 삭제 버튼을 추가해주겠습니다. 이 때, 반드시 key 값을 설정해주어야 합니다. use_container_width 옵션은 True로 설정해서 버튼의 너비를 조정하겠습니다.
...
with st.expander(label=f"**{i+j+1}. {pokemon['name']}**", expanded=True):
...
delete_button = st.button(label="삭제", key=i+j, use_container_width=True)
삭제 버튼 로직 추가
삭제 버튼 아래에 조건문을 추가해서 session_state에서 특정 포켓몬을 삭제하는 로직을 추가하겠습니다.
...
with st.expander(label=f"**{i+j+1}. {pokemon['name']}**", expanded=True):
...
delete_button = st.button(label="삭제", key=i+j, use_container_width=True)
if delete_button:
del st.session_state.pokemons[i+j]
그 다음 삭제 버튼을 눌러보면 삭제가 되긴 하는데, 엉뚱한 포켓몬이 삭제되거나 바로바로 삭제되지 않는 현상이 발생합니다! 이는 button을 눌렀을 때 session_state를 조작하면 발생하는 현상입니다.
streamlit button 동작 방식
streamlit 버튼이 동작하는 방식을 확인하기 위해서 페이지 최상단과 버튼을 눌렀을 때의 조건문에 print문을 추가하겠습니다.
import streamlit as st
print("page reload")
...
with st.expander(label=f"**{i+j+1}. {pokemon['name']}**", expanded=True):
...
delete_button = st.button(label="삭제", key=i+j, use_container_width=True)
if delete_button:
print("button click!")
del st.session_state.pokemons[i+j]
그 다음 버튼을 눌러보면 “button click!”이 출력되기 전에 “page reload”가 출력되는 것을 확인할 수 있습니다. 즉, 버튼을 누르면 페이지가 한번 리로딩 되고 그 다음 버튼 아래 조건문이 실행되면서 session_state에 저장된 포켓몬을 삭제하는 것입니다. 그 뒤에 페이지 리로드를 하지 않기 때문에 삭제된 포켓몬이 화면에서 즉각 사라지지 않았던 것입니다.
st.rerun()
삭제된 포켓몬을 화면에서 바로 제거해주기 위해선 session_state를 조작한 뒤, 곧바로 페이지 리로딩을 직접 수행해주는 것입니다. 이는 st.rerun() 함수를 사용해서 구현할 수 있습니다. print 문은 제거하고, 포켓몬을 삭제한 뒤 페이지를 리로딩하도록 코드를 작성해보겠습니다.
with st.expander(label=f"**{i+j+1}. {pokemon['name']}**", expanded=True):
...
delete_button = st.button(label="삭제", key=i+j, use_container_width=True)
if delete_button:
del st.session_state.pokemons[i+j]
st.rerun()
streamlit button 심화
button을 잘 다루는 것은 생각보다 까다롭습니다. streamlit 공식 문서에서 버튼의 내부 동작 원리와 심화 응용 사례들을 잘 정리해놓은 문서가 있으니, 궁금하신 분들은 읽어보시길 권합니다.
streamlit button 심화 문서: https://docs.streamlit.io/library/advanced-features/button-behavior-and-examples
정리
이번 챕터에서는 button을 이용해서 등록되어 있는 포켓몬을 삭제하는 기능을 구현해봤습니다. 단순한 기능으로 보였으나, session_state와 함께 사용하다보니 까다로운 부분들이 있었습니다. button에서 session_state를 조작할 때는 st.rerun()을 함께 사용해준다는 것을 기억하고 넘어갔으면 좋겠습니다.