| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [View Raw Code] [Original HTTPS Page] |
PythonNative drives the UI through a small, predictable cycle: render, commit, effects, and an optional drain. This page walks through what happens at each step, how navigation changes fold into it, and where you can hook in.
A render pass is triggered by:
A use_state / use_reducer setter re-renders locally: only the component that owns the changed state (and the subtree it returns) is re-run. Setters never render inline: every setter call made during one callback, effect, or task step lands in the same flush, scheduled on the application loop (automatic batching), on every host including headless tests. Sibling and ancestor components retain their native views and hook state unless their own inputs or context change. Screens and mounted list rows belong to the same logical tree. Navigation updates that tree, and Fast Refresh preserves compatible component instances.
The phases:
[render] -> [commit + layout] -> [layout effects] -> [passive effects] -> drain? -> [render] ...
[use_effect(fn, deps)][pythonnative.use_effect] fires after each commit when its deps list changes (or every commit if deps is omitted). This is right for subscriptions, timers, and synchronization with mutable globals.
[use_focus_effect(fn, deps)][pythonnative.use_focus_effect] is identical in shape but only fires when the screen is focused (and its cleanup runs when the screen is blurred). Use it for camera streams, GPS subscriptions, and anything that should be released as soon as the user navigates away.
!!! tip "Effects can be coroutines" Both hooks accept an async def callback. The coroutine runs as a task on the framework loop and is cancelled automatically when the effect re-runs, the screen blurs (for focus effects), or the component unmounts; no manual task bookkeeping is needed. See the Async + data guide.
For a class-component-style mental model:
| Class lifecycle | PythonNative equivalent |
|---|---|
| componentDidMount | use_effect(fn, deps=[]) |
| componentDidUpdate | use_effect(fn, deps=[a, b]) |
| componentWillUnmount | the cleanup function returned from use_effect |
| getDerivedStateFromProps | a plain expression at the top of the component |
| getSnapshotBeforeUpdate | use_layout_effect (inspect committed geometry before passive effects) |
When a screen mounts inside a navigator (stack, tab, or drawer):
When the user navigates away:
The screen host forwards the platform's app-level lifecycle to navigators and effects:
You can opt into these directly in app code by writing an effect that checks the navigation handle's is_focused() state, but most apps should reach for the [use_focus_effect][pythonnative.use_focus_effect] hook instead.
import asyncio
import pythonnative as pn
@pn.component
def LiveClock() -> pn.Node:
now, set_now = pn.use_state("--:--")
async def tick():
while True:
set_now(_format_now())
await asyncio.sleep(1)
pn.use_focus_effect(tick, deps=[])
return pn.Text(now, style={"font_size": 48})| Back | FazBrowse Home | New Git URL |