Skip to content

Component

The @component decorator turns a plain function into a Component: calling it returns an Element instead of running the body, and the reconciler runs the body (with hooks) when the element mounts or its props change. Positional arguments are children; keyword arguments are props. memo skips re-rendering when props are unchanged.

The @component decorator and the Component type.

A component is a plain Python function that takes props and returns a Node: an Element, a list of elements, or None. Decorating it with @component turns it into a Component: a callable that describes a render (it returns an Element whose type is the component) instead of performing one. The reconciler invokes the function body later, with hook state installed.

The decorator preserves the function's signature for type checkers via :class:typing.ParamSpec, so Greeting(nme="x") is a static error and editors autocomplete props from the function definition.

Children

Children are positional. A component that accepts children declares a *children parameter, exactly like the built-in containers:

@pn.component
def Card(*children: pn.Element, title: str = "") -> pn.Element:
    return pn.Column(pn.Text(title, style=pn.style(bold=True)), *children)

Card(pn.Text("body"), title="Hello")

Positional arguments to a component without *children bind to its positional parameters, so Greeting("World") works for def Greeting(name: str).

Keys

Every component accepts key= at the call site for keyed reconciliation. key is consumed by the framework and is not passed to the function unless the function declares a key parameter itself. Declaring it (key: str | None = None) is the way to keep strict type checkers happy when a component is rendered in a list; otherwise use Element.with_key.

Classes:

Name Description
Component

A render-function wrapped by @component.

Functions:

Name Description
component

Turn a render function into a Component.

memo

Skip a component's render when its props haven't changed.

is_component

Return whether obj is a Component.

Attributes:

Name Type Description
RenderFn

A component body: returns a Node, or awaits one when async def.

RenderFn module-attribute

RenderFn = Callable[P, Union[Node, Awaitable[Node]]]

A component body: returns a Node, or awaits one when async def.

Component

Component(
    fn: RenderFn[P], *, display_name: Optional[str] = None
)

Bases: Generic[P]

A render-function wrapped by @component.

Calling a Component does not run the function; it returns an Element describing the call so the reconciler can mount it, preserve its hook state across renders, and re-run it when its state or props change.

Attributes:

Name Type Description
fn

The original render function.

display_name

Name shown in diagnostics and dev tooling (defaults to fn.__name__).

memoized

Whether memo was applied, in which case the reconciler skips re-rendering this component when its props are shallowly equal to the previous render.

accepts_children

Whether fn declares *children.

Methods:

Name Description
render

Invoke the render function for element.

is_async property

is_async: bool

Whether the render function is an async def.

render

render(element: Element) -> Any

Invoke the render function for element.

Children stored on the element are passed positionally; props are passed by keyword. Returns whatever the function returned (an element, a list, None, or a coroutine for async def bodies).

component

component(fn: RenderFn[P]) -> Component[P]

Turn a render function into a Component.

The decorated function may use hooks (use_state, use_effect, etc.) and returns an Element tree, a list of elements, or None. Each call site creates an independent component instance with its own hook state.

Parameters:

Name Type Description Default
fn RenderFn[P]

The render function. May be async def; the body is then driven by the reconciler and suspends on pending awaits (see Suspense).

required

Returns:

Type Description
Component[P]

A Component whose call signature mirrors fn (plus the

Component[P]

framework key= keyword).

Example
import pythonnative as pn

@pn.component
def Greeting(name: str = "World"):
    return pn.Text(f"Hello, {name}!")

memo

memo(
    target: Optional[Component[P]] = None,
    *,
    equal: Optional[
        Callable[[Dict[str, Any], Dict[str, Any]], bool]
    ] = None
) -> Any

Skip a component's render when its props haven't changed.

Apply on top of @component. When the reconciler re-renders the parent tree, a memoized child is skipped (its previously-rendered subtree is reused) iff its props and children are equal to the previous render and none of its own state setters fired. Props are compared shallowly by default: callables by identity, everything else by ==.

Pair with use_callback when passing callbacks as props, otherwise a fresh closure defeats the memo.

Parameters:

Name Type Description Default
target Optional[Component[P]] None
equal Optional[Callable[[Dict[str, Any], Dict[str, Any]], bool]]

Optional custom comparator (old_props, new_props) -> bool replacing the shallow comparison.

None

Returns:

Type Description
Any

The same component, marked for memoization (or a decorator when

Any

called with keyword arguments only).

Example
@pn.memo
@pn.component
def ExpensiveRow(label: str):
    ...

@pn.memo(equal=lambda a, b: a["id"] == b["id"])
@pn.component
def Row(id: int, extra: dict):
    ...

is_component

is_component(obj: Any) -> bool

Return whether obj is a Component.

Next steps