Execution Results
Execution results are objects returned from command handlers that control how components respond to user actions. They determine which components need re-rendering, what HTTP headers to set, and how the browser should behave after processing a command.
Overview
Command handlers can return different types of execution results to control the response behavior:
- Component rendering control - Mark components as dirty (needing re-render) or clean
- Navigation control - Redirect to different pages or refresh the current page
- URL management - Update the browser URL without full page reload
If a command handler returns None
(or doesn't return anything), the component is automatically marked as dirty and will be re-rendered.
Available Execution Results
ComponentClean
Indicate that a component is clean and requires no re-rendering.
Use this when a command performs side effects (like logging, analytics, or background tasks) that don't change the component's visual state.
Example:
class AnalyticsComponent(LiveComponent):
...
@command
def track_click(self, call_context: CallContext[AnalyticsState], event_name: str):
"""Log user action without re-rendering the component"""
self.analytics.track(event_name, call_context.state.user_id)
return ComponentClean()
ComponentDirty
Mark a component as dirty to trigger re-rendering.
This is the default behavior when a command handler returns None.
Example:
class StockComponent(LiveComponent):
...
@command
def update_stock(self, call_context: CallContext[StockState]):
"""Update stock quantity. Component automatically re-renders"""
call_context.state.bean.stock_quantity += 1
call_context.state.bean.save()
# Returns ComponentDirty() by default
ParentDirty
Mark the parent component as dirty to trigger re-rendering.
Useful when a child component performs an action that affects the parent's data, such as deleting an item from a list or updating shared state.
Example:
class CartComponent(LiveComponent):
...
@command
def add_to_cart(self, call_context: CallContext[CartState], product_id: int):
"""Add item to cart and update parent cart counter"""
self.state.cart.append(product_id)
return ParentDirty()
RedirectPage
Redirect the browser to a different URL.
Sets the HX-Redirect header to instruct HTMX to navigate to a new page. Commonly used after successful form submissions or authentication.
Example:
class LoginComponent(LiveComponent):
...
@command
def login(self, call_context: CallContext[LoginState], username: str, password: str):
"""Authenticate user and redirect to dashboard"""
user = authenticate(username=username, password=password)
if user:
login(call_context.request, user)
return RedirectPage('/dashboard/')
call_context.state.error = 'Invalid credentials'
RefreshPage
Trigger a full page refresh in the browser.
Sets the HX-Refresh header to instruct HTMX to reload the entire page. Use sparingly, as it breaks the SPA-like experience.
Example:
class SettingsComponent(LiveComponent):
...
@command
def switch_language(self, call_context: CallContext[SettingsState], language: str):
"""Switch language and refresh page to apply changes"""
call_context.request.session['language'] = language
return RefreshPage()
ReplaceUrl
Replace the current URL in the browser without reloading the page.
Updates the browser's address bar and history without triggering a full page reload. Useful for maintaining clean URLs that reflect the current application state. See https://htmx.org/headers/hx-replace-url/.
Example:
class ProductListComponent(LiveComponent):
...
@command
def apply_search_filter(self, call_context: CallContext[ProductListState], search_term: str):
"""Apply search filter and update URL to reflect current state"""
call_context.state.search = search_term
if search_term:
return ReplaceUrl(f'/products/?search={search_term}')
else:
return ReplaceUrl('/products/')
More Usage Examples
Basic Component Control
When you need explicit control over component rendering:
from livecomponents import LiveComponent, command, CallContext
from livecomponents.manager.execution_results import ComponentDirty, ComponentClean
class DataComponent(LiveComponent):
@command
def update_data(self, call_context: CallContext[DataState]):
"""Update component state and trigger re-render"""
call_context.state.data = "new value"
# Component will be re-rendered (default behavior)
return ComponentDirty()
@command
def log_action(self, call_context: CallContext[DataState]):
"""Log user action without triggering component re-render"""
self.analytics.track("button_clicked", call_context.state.user_id)
return ComponentClean()
Cross-Component Updates
When child components need to update their parents or siblings:
class ProductRowComponent(LiveComponent):
@command
def update_sibling(self, call_context: CallContext[ProductRowState]):
"""Update product data and refresh related sidebar component"""
self.update_product_stats()
return ComponentDirty("product-sidebar")
@command
def delete_product(self, call_context: CallContext[ProductRowState]):
"""Delete product and refresh parent product list"""
call_context.state.product.delete()
return ParentDirty()
Multiple Results
Command handlers can return a list of execution results to perform multiple actions:
class OrderComponent(LiveComponent):
@command
def complete_order(self, call_context: CallContext[OrderState]):
"""Complete order with multiple UI updates"""
order = call_context.state.order
order.status = "completed"
order.save()
return [
ComponentDirty(), # Re-render current component
ComponentDirty("cart-counter"), # Update cart count
ReplaceUrl(f"/orders/{order.id}/confirmation/") # Update URL
]