Hooks¶
Hook primitives for @component functions: state, effects, memoization,
context, and refs. Hooks must be called at the top level of a component
(not inside conditionals or loops) so they can be matched to the same
slot across renders.
Hook primitives for function components.
Provides React-like hooks for managing state, effects, memoization,
context, and navigation within function components decorated with
component. Hooks must be called at the top
level of a component (not inside conditionals or loops) so they map to
the same slot across renders. In dev mode the framework verifies this
and raises HookOrderError
on a violation instead of silently cross-wiring state.
Two effect phases exist, mirroring React:
use_layout_effectcallbacks run synchronously inside the commit, after native mutations and the layout pass have been applied. They can measure committed frames and issue imperative view commands before the user sees the new frame.use_effectcallbacks (passive effects) run after the layout effects, at the end of the same commit.
Example
Classes:
| Name | Description |
|---|---|
Ref |
Mutable container returned by |
HookState |
Per-instance storage for one component's hooks. |
QueryResult |
Snapshot of a |
MutationState |
Snapshot of a |
MutationCall |
Awaitable handle returned by a mutator trigger. |
Context |
Container for a value shared across a subtree. |
NavigationHandle |
Handle returned by |
Functions:
| Name | Description |
|---|---|
batch_updates |
Coalesce multiple state updates into a single re-render. |
use_state |
Return |
use_reducer |
Return |
use_effect |
Schedule a side effect to run after the native commit. |
use_layout_effect |
Schedule a side effect that runs synchronously inside the commit. |
use_memo |
Return a memoized value that is recomputed only when |
use_callback |
Return a stable reference to |
use_ref |
Return a |
use_imperative_handle |
Publish a controller object on |
use_async_effect |
Schedule an async effect that's cancelled on re-run / unmount. |
use_query |
Subscribe to an async fetcher and re-render when its result changes. |
use_mutation |
Wrap an async mutator with loading/error state and a trigger. |
use_window_dimensions |
Return the current viewport size and re-render when it changes. |
use_safe_area_insets |
Return the current safe-area insets and re-render on change. |
use_keyboard_height |
Return the on-screen keyboard height (or 0) and re-render on change. |
use_color_scheme |
Return the effective color scheme and re-render when it changes. |
create_context |
Create a new context with an optional default value. |
use_context |
Read the current value of |
Provider |
Provide |
memo |
Skip a function component's render when its props haven't changed. |
use_navigation |
Return a |
use_back_handler |
Intercept the system back action for this screen. |
component |
Mark a function as a PythonNative component. |
Ref
¶
Ref(initial: Optional[T] = None)
Bases: Generic[T]
Mutable container returned by use_ref.
A Ref holds one value on its current attribute. Mutating
current never triggers a re-render, which makes refs the right
place for timers, last-seen values, and imperative handles.
When a Ref is passed to a built-in element via the ref=
prop, the reconciler populates current with the underlying
native view (UIView on iOS, android.view.View on Android,
a Tk widget on desktop) after commit, and clears it back to
None on unmount. Composite components (e.g.
FlatList) instead publish a typed
controller object on current via
use_imperative_handle.
Attributes:
| Name | Type | Description |
|---|---|---|
current |
Optional[T]
|
The referenced value. |
HookState
¶
Per-instance storage for one component's hooks.
Each @component instance owns one HookState. Hooks are matched
to slots by call order, so they must always be called in the same
order across renders. Effects scheduled during render are deferred
(layout effects into _pending_layout_effects, passive effects
into _pending_effects) and flushed by the reconciler in two
phases after native mutations commit.
Attributes:
| Name | Type | Description |
|---|---|---|
states |
List[Any]
|
One entry per |
effects |
List[Tuple[Any, Any]]
|
One |
layout_effects |
List[Tuple[Any, Any]]
|
One |
memos |
List[Tuple[Any, Any]]
|
One |
refs |
List[Ref]
|
One |
Methods:
| Name | Description |
|---|---|
begin_render |
Prepare for a render pass: reset cursors and the dev-mode hook log. |
finish_render |
Finalize a successful render: lock in / verify the hook signature. |
record_hook |
Record a hook call for the dev-mode order guard. |
reset_hook_signature |
Forget the recorded hook signature (used by Fast Refresh). |
flush_layout_effects |
Run layout effects queued during render (commit phase, pre-paint). |
flush_pending_effects |
Run passive effects queued during render, after native commit. |
cleanup_all_effects |
Run every outstanding cleanup function, then clear state. |
begin_render
¶
begin_render(component_name: str = '') -> None
Prepare for a render pass: reset cursors and the dev-mode hook log.
Called by the reconciler before each invocation of the component body so the next render reads slots in the same order they were written.
finish_render
¶
Finalize a successful render: lock in / verify the hook signature.
Only called when the component body returned without raising, so a failed render never corrupts the signature.
Raises:
| Type | Description |
|---|---|
HookOrderError
|
In dev mode, when this render called fewer hooks than the previous one. |
record_hook
¶
record_hook(kind: str) -> None
Record a hook call for the dev-mode order guard.
Raises:
| Type | Description |
|---|---|
HookOrderError
|
In dev mode, when the hook at this position differs from (or extends past) the previous render. |
reset_hook_signature
¶
Forget the recorded hook signature (used by Fast Refresh).
After a hot reload swaps in a new component body, the old signature no longer applies; the next render records a fresh one.
flush_layout_effects
¶
Run layout effects queued during render (commit phase, pre-paint).
flush_pending_effects
¶
Run passive effects queued during render, after native commit.
For each pending effect, the previous cleanup is invoked first (if any), then the new effect callback. The new return value becomes the next cleanup.
cleanup_all_effects
¶
Run every outstanding cleanup function, then clear state.
Layout-effect cleanups run before passive-effect cleanups, matching the mount order in reverse. Called when the component instance is unmounted by the reconciler.
QueryResult
dataclass
¶
QueryResult(data: Optional[T] = None, loading: bool = True, error: Optional[BaseException] = None, refetch: Callable[[], None] = lambda: None)
Bases: Generic[T]
Snapshot of a use_query subscription.
Attributes:
| Name | Type | Description |
|---|---|---|
data |
Optional[T]
|
The most recent successful result, or the |
loading |
bool
|
|
error |
Optional[BaseException]
|
The exception raised by the most recent failed fetch,
or |
refetch |
Callable[[], None]
|
A zero-arg callable that triggers a refetch. Stable across renders. |
MutationState
dataclass
¶
MutationState(data: Optional[T] = None, loading: bool = False, error: Optional[BaseException] = None)
Bases: Generic[T]
Snapshot of a use_mutation subscription.
Attributes:
| Name | Type | Description |
|---|---|---|
data |
Optional[T]
|
The most recent successful return value of the mutator,
or |
loading |
bool
|
|
error |
Optional[BaseException]
|
The exception raised by the most recent failed
mutation, or |
MutationCall
¶
MutationCall(future: Any)
Bases: Generic[T]
Awaitable handle returned by a mutator trigger.
Returned by the second element of the
use_mutation tuple. Awaiting the
handle resolves to the mutator's return value (or re-raises its
exception); discarding the handle is safe. Python won't warn
about an unawaited coroutine because this is a plain object.
Example
Methods:
| Name | Description |
|---|---|
cancel |
Cancel the underlying mutation. Returns whether cancellation succeeded. |
done |
Whether the underlying mutation has finished. |
Context
¶
Context(default: Any = None)
Container for a value shared across a subtree.
Created by create_context; consumed
via use_context. Use
Provider to set the value for a subtree.
Context is reactive: when a Provider's value changes, every component that read the context on its last render re-renders, even if a memoized ancestor skipped its own re-render.
Attributes:
| Name | Type | Description |
|---|---|---|
default |
The value returned when no |
NavigationHandle
¶
NavigationHandle(host: Any)
Handle returned by use_navigation.
Wraps the host's push/pop primitives so screens can navigate
without knowing the underlying native navigation stack. The
typical user-facing surface is the declarative handle returned by
a Stack; this class is
the lower-level fallback used when no navigator is rendered (and
as the bridge that declarative navigators delegate to when they
need to push real native screens).
Example
Methods:
| Name | Description |
|---|---|
navigate |
Push |
go_back |
Pop the current screen and return to the previous one. |
get_params |
Return the params dict passed to this screen. |
navigate
¶
Push component onto the navigation stack.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
component
|
Any
|
A |
required |
params
|
Optional[Dict[str, Any]]
|
Optional dict of arguments serialized into the target screen. |
None
|
batch_updates
¶
batch_updates() -> Generator[None, None, None]
Coalesce multiple state updates into a single re-render.
State setters called inside the with block defer their
re-render trigger until the block exits, so any number of
set_* calls produce at most one render pass.
Yields:
| Type | Description |
|---|---|
None
|
None. The block executes normally; deferred renders fire on |
None
|
exit. |
use_state
¶
Return (value, setter) for component-local state.
State persists across re-renders of the same component instance.
The setter accepts a value or a current -> new callable; calling
it with an unchanged value is a no-op (no re-render).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
initial
|
Any
|
Initial state value. If callable, it is invoked once on the first render (lazy initialization). |
None
|
Returns:
| Type | Description |
|---|---|
Any
|
A 2-tuple |
Callable
|
state and |
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If called outside a |
use_reducer
¶
Return (state, dispatch) for reducer-based state management.
A reducer is a pure function that takes the current state and an
action and returns the next state. Use it instead of
use_state when state transitions are
complex enough that centralizing them in one function aids
readability and testing.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
reducer
|
Callable[[Any, Any], Any]
|
|
required |
initial_state
|
Any
|
Initial state value, or a callable invoked once on the first render. |
required |
Returns:
| Type | Description |
|---|---|
Any
|
A 2-tuple |
Callable
|
reducer with the supplied action. |
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If called outside a |
Example
import pythonnative as pn
def reducer(state, action):
if action == "increment":
return state + 1
if action == "reset":
return 0
return state
@pn.component
def Counter():
count, dispatch = pn.use_reducer(reducer, 0)
return pn.Row(
pn.Button("+", on_press=lambda: dispatch("increment")),
pn.Button("Reset", on_press=lambda: dispatch("reset")),
)
use_effect
¶
Schedule a side effect to run after the native commit.
Effects are queued during the render pass and flushed once the reconciler has finished applying all native-view mutations, which means effect callbacks can safely measure layout or interact with committed native views.
The deps argument controls when the effect re-runs:
None: every render.[]: mount only.[a, b]: whenaorbchange (compared by identity, then==).
effect may return a cleanup callable; the previous cleanup runs
before the next effect (and on unmount).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
effect
|
Callable
|
A zero-arg callable invoked after commit. Optionally returns a cleanup callable. |
required |
deps
|
Optional[list]
|
Dependency list, or |
None
|
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If called outside a |
use_layout_effect
¶
Schedule a side effect that runs synchronously inside the commit.
Like use_effect, but the callback
fires before passive effects, immediately after native mutations
and the layout pass are applied. Use it when you need to measure a
committed frame (via a Ref) or issue an
imperative view command before the user sees the new frame, for
example scrolling a list into position on mount.
Prefer use_effect for everything else; layout effects block the
commit, so heavy work here delays the frame.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
effect
|
Callable
|
A zero-arg callable invoked during commit. Optionally returns a cleanup callable. |
required |
deps
|
Optional[list]
|
Dependency list, or |
None
|
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If called outside a |
Example
import pythonnative as pn
@pn.component
def AutoScrollList(items):
list_ref = pn.use_ref()
def scroll_to_bottom():
if list_ref.current is not None:
list_ref.current.scroll_to_end(animated=False)
pn.use_layout_effect(scroll_to_bottom, [len(items)])
return pn.FlatList(items, render_item=Row, ref=list_ref)
use_memo
¶
Return a memoized value that is recomputed only when deps change.
Use this for expensive computations whose inputs change rarely. For cheap computations, plain inline code is faster (memoization itself has overhead).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
factory
|
Callable[[], T]
|
Zero-arg callable returning the value. |
required |
deps
|
list
|
Dependency list. The value is recomputed when any element differs from the previous render. |
required |
Returns:
| Type | Description |
|---|---|
T
|
The cached or freshly computed value. |
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If called outside a |
use_callback
¶
Return a stable reference to callback, refreshed when deps change.
Equivalent to use_memo(lambda: callback, deps). Useful when passing
a function as a prop to a memoized child component, so the child
doesn't see a fresh function identity on every render.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
callback
|
Callable
|
The callable to memoize. |
required |
deps
|
list
|
Dependency list controlling when the reference refreshes. |
required |
Returns:
| Type | Description |
|---|---|
Callable
|
A callable with stable identity across renders (until |
use_ref
¶
Return a Ref that persists across renders.
Refs are useful for storing values that must survive renders without triggering them: timers, last-seen values, native handles, and so on.
ref.current is also populated by the reconciler with the
underlying native view (UIView on iOS, android.view.View on
Android, a Tk widget on desktop) when the ref is passed via the
ref= prop on a built-in element, and cleared to None when
that element unmounts. Composite components such as
FlatList publish a typed controller
object instead (see
use_imperative_handle).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
initial
|
Optional[T]
|
Value placed at |
None
|
Returns:
| Type | Description |
|---|---|
Ref[T]
|
A |
Ref[T]
|
not trigger re-renders. |
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If called outside a |
use_imperative_handle
¶
use_imperative_handle(ref: Optional[Ref], factory: Callable[[], Any], deps: Optional[list] = None) -> None
Publish a controller object on ref.current.
The composite-component counterpart to passing ref= to a
built-in element. Call it inside a component that accepts a
ref prop to expose a curated imperative API (rather than the
raw native view) to the parent. The handle is installed during the
commit's layout-effect phase and cleared back to None on
unmount.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ref
|
Optional[Ref]
|
The |
required |
factory
|
Callable[[], Any]
|
Zero-arg callable returning the handle object. |
required |
deps
|
Optional[list]
|
Dependency list controlling when the handle is rebuilt.
Defaults to |
None
|
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If called outside a |
use_async_effect
¶
Schedule an async effect that's cancelled on re-run / unmount.
Like use_effect but takes an
async def (or any zero-arg callable returning an awaitable).
The coroutine is scheduled on the framework runtime via
run_async after the native
commit. When deps change (or the component unmounts), the
in-flight future is cancelled.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
effect
|
Callable[[], Awaitable[None]]
|
A zero-arg callable returning an awaitable. Typically
an |
required |
deps
|
Optional[list]
|
Dependency list, or |
None
|
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If called outside a |
use_query
¶
use_query(fetcher: Callable[[], Awaitable[T]], deps: Optional[list] = None, *, initial: Optional[T] = None) -> QueryResult[T]
Subscribe to an async fetcher and re-render when its result changes.
The fetcher is called on mount and any time deps change, with
cancellation propagated when the component unmounts mid-fetch.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
fetcher
|
Callable[[], Awaitable[T]]
|
Zero-arg |
required |
deps
|
Optional[list]
|
Dependency list. Refetches whenever any entry changes. |
None
|
initial
|
Optional[T]
|
Optional starting value for |
None
|
Returns:
| Type | Description |
|---|---|
QueryResult[T]
|
A frozen |
QueryResult[T]
|
|
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If called outside a |
use_mutation
¶
use_mutation(mutator: Callable[..., Awaitable[T]]) -> Tuple[MutationState[T], Callable[..., MutationCall[T]]]
Wrap an async mutator with loading/error state and a trigger.
Returns (state, mutate). Call mutate(*args, **kwargs) to
invoke the mutator; state reflects loading/error/data and
re-renders on each transition. mutate returns a
MutationCall you can await for
the result, or discard for fire-and-forget.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mutator
|
Callable[..., Awaitable[T]]
|
An |
required |
Returns:
| Type | Description |
|---|---|
Tuple[MutationState[T], Callable[..., MutationCall[T]]]
|
A 2-tuple |
use_window_dimensions
¶
Return the current viewport size and re-render when it changes.
Equivalent to React Native's useWindowDimensions. The values
are pushed by the screen host whenever the platform reports a new
size (initial layout, rotation, multitasking split-view).
Returns:
| Type | Description |
|---|---|
Dict[str, float]
|
A dict with |
Dict[str, float]
|
units (pt on iOS, dp on Android). Both are |
Dict[str, float]
|
screen host has run its first layout pass. |
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If called outside a |
use_safe_area_insets
¶
Return the current safe-area insets and re-render on change.
Mirrors react-native-safe-area-context's useSafeAreaInsets.
Returns:
| Type | Description |
|---|---|
Dict[str, float]
|
A dict with |
Dict[str, float]
|
floats in layout units (pt on iOS, dp on Android). |
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If called outside a |
use_keyboard_height
¶
use_keyboard_height() -> float
Return the on-screen keyboard height (or 0) and re-render on change.
Useful for custom layout that needs to react to keyboard
show/hide events. Most apps should use
KeyboardAvoidingView instead
of reading this directly.
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If called outside a |
use_color_scheme
¶
use_color_scheme() -> str
Return the effective color scheme and re-render when it changes.
Equivalent to React Native's useColorScheme. The system value
is published by the screen host; an app-level override set through
appearance.set_color_scheme
takes precedence.
Returns:
| Type | Description |
|---|---|
str
|
|
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If called outside a |
create_context
¶
Create a new context with an optional default value.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
default
|
Any
|
Returned by |
None
|
Returns:
| Type | Description |
|---|---|
Context
|
A fresh |
use_context
¶
Read the current value of context from the nearest Provider.
If no enclosing Provider exists, returns the context's default.
The component is registered as a subscriber: when the nearest
Provider's value changes, the component re-renders even if a
memoized ancestor skipped.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
context
|
Context
|
The |
required |
Returns:
| Type | Description |
|---|---|
Any
|
The current value for |
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If called outside a |
Provider
¶
Provide value for context to all descendants of children.
Accepts any number of children (varargs). A Provider contributes no native view of its own; its children mount directly into the surrounding native parent.
When value differs from the previous render (identity, then
==), every descendant that read the context via
use_context re-renders, including
descendants of memoized components that skipped.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
context
|
Context
|
The |
required |
value
|
Any
|
Value made available to descendants via
|
required |
*children
|
Element
|
Subtree(s) under which the provider applies. |
()
|
Returns:
| Type | Description |
|---|---|
Element
|
An |
Element
|
as a context boundary. |
memo
¶
Skip a function component's render when its props haven't changed.
Decorate a @component-wrapped function to opt into shallow-prop
memoization. When the reconciler re-renders the parent tree, a
memoized child is skipped (its previously-rendered subtree is
reused) iff:
- Its props are shallowly equal to the previous render's props
(callables compared by identity, scalars by
==). - None of its internal
use_state/use_reducersetters fired since the last render.
Pair with use_callback when passing
callbacks as props, otherwise a fresh closure will defeat the memo.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
component_fn
|
Callable[..., Element]
|
A function previously decorated with
|
required |
Returns:
| Type | Description |
|---|---|
Callable[..., Element]
|
The same function, marked for memoization. |
use_navigation
¶
use_navigation() -> NavigationHandle
Return a NavigationHandle for the screen.
Returns:
| Type | Description |
|---|---|
NavigationHandle
|
The handle bound to the current screen's host. |
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If called outside a component rendered via
|
use_back_handler
¶
Intercept the system back action for this screen.
On Android this handles the hardware back button and predictive back gesture; in the desktop preview it handles the Escape key. iOS has no system back button, so the handler never fires there (swipe-back is controlled by the navigation stack instead).
Handlers registered later run first, so a component mounted on top
of existing content (a modal, a confirmation sheet) takes priority
over handlers that were already mounted. Return True to consume
the event and stop both remaining handlers and the platform's
default behavior (popping the screen); return False to pass it
along.
The latest handler closure from the most recent render is
always the one invoked; registration order is fixed at mount, so
re-renders never change priority.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
handler
|
Callable[[], bool]
|
Zero-arg callable returning |
required |
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If called outside a |
component
¶
Mark a function as a PythonNative component.
The decorated function may use hooks (use_state, use_effect,
etc.) and returns an Element tree.
Each call site creates an independent component instance with its
own hook state.
Positional arguments are mapped onto the function's positional
parameters. If the function declares *args, positional arguments
instead become the special children prop.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
func
|
Callable
|
The function to wrap. |
required |
Returns:
| Type | Description |
|---|---|
Callable[..., Element]
|
A wrapper that, when called, returns an |
Callable[..., Element]
|
is |
Async hooks¶
For coroutines and data-driven UI, PythonNative ships dedicated
async-aware hooks layered on top of use_state / use_effect:
use_async_effect: async sibling ofuse_effect; cancels the in-flight coroutine on re-run / unmount.use_query: subscribes to an async fetcher and re-renders on data / error / refetch.use_mutation: wraps an async mutator with loading / error state and a trigger.use_persisted_state:use_statebacked byAsyncStorage.
See the Async + data guide for a complete walkthrough.
Platform-metric hooks¶
These hooks subscribe to values published by
pythonnative.platform_metrics and re-render the component when they
change. The screen host is the only code that updates the underlying
values; user code consumes them.
use_window_dimensions: viewport size.use_safe_area_insets: top/bottom/left/right insets.use_keyboard_height: software keyboard height.
For most apps the dedicated
KeyboardAvoidingView component
is preferable to consuming use_keyboard_height directly.
Next steps¶
- Compose hooks into a screen: Components.
- Run side effects from
use_effect(after commit) anduse_focus_effect(after focus). - Share state across the tree with
create_contextandProvider. - Animate without re-rendering using
use_ref Animated; see the Animations guide.