Skip to content

Context

wybthon.context

context

Context: pass values down the tree without threading props.

A Context is created with create_context and is its own provider: call it with a value and children to expose that value to every descendant, and read it with use_context.

Values live on the reactive ownership tree, so use_context works anywhere an owner exists: component bodies, effects, memos, and list rows. The value is handed to consumers exactly as provided, so pass a signal (or any accessor) when consumers should react to changes.

Example
Theme: Context[Accessor[str]] = create_context()

@component
def Button():
    theme = use_context(Theme)
    return button("Hi", class_=lambda: f"btn-{theme()}")

@component
def App():
    theme, set_theme = create_signal("light")
    return Theme(theme, Button())   # value first, then children

Classes:

Name Description
ContextNotFoundError

Raised by use_context when no provider is found and no default exists.

Context

A context token that also acts as its provider component.

Functions:

Name Description
create_context

Create a Context.

use_context

Read the nearest provided value for ctx.

ContextNotFoundError

Bases: LookupError

Raised by use_context when no provider is found and no default exists.

Context

Context(default: Any = _MISSING, name: str | None = None)

A context token that also acts as its provider component.

Created by create_context. Calling the context with a value and children returns a provider VNode:

Theme(value, *children)
Theme("dark", App())
Theme(lambda: theme(), App())     # reactive value

Attributes:

Name Type Description
default

Value returned by use_context when no provider is found, if one was declared.

name

Optional label for diagnostics.

has_default property

has_default: bool

Whether the context was created with a default value.

create_context

create_context(default: T, *, name: str | None = None) -> Context[T]
create_context(*, name: str | None = None) -> Context[T]
create_context(default: Any = _MISSING, *, name: str | None = None) -> Context[Any]

Create a Context.

Parameters:

Name Type Description Default
default Any

Optional value returned by use_context when no provider is above the reader. Without one, reading outside a provider raises ContextNotFoundError.

_MISSING
name str | None

Optional label for diagnostics.

None

Returns:

Type Description
Context[Any]

A new Context; call it to provide, pass it to use_context to read.

use_context

use_context(ctx: Context[T]) -> T

Read the nearest provided value for ctx.

Walks up the ownership tree from the active scope and returns the value exactly as the provider received it: a signal or accessor stays a signal or accessor (call it where you need the value), a static value is returned directly.

Raises:

Type Description
ContextNotFoundError

No provider is above the caller and the context has no default.

What's in this module

Context passes a value down the tree without threading props. A Context created by create_context is its own provider: call it with a value and children to expose that value to every descendant, and read it with use_context. Values live on the ownership tree, so use_context works anywhere an owner exists: component bodies, effects, memos, and For rows.

Name Description
create_context create_context(default=..., *, name=None); without a default, reading outside a provider raises.
Context The token; Theme(value, *children) returns a provider VNode. .default, .name, .has_default.
use_context Nearest provided value, returned exactly as provided (an accessor stays an accessor).
ContextNotFoundError Raised when no provider is above the reader and the context has no default.

The value is handed to consumers exactly as provided, so pass a signal or accessor when consumers should react to changes, and call it where you need the value.

from wybthon import Accessor, Context, button, component, create_context, create_signal, div, use_context

Theme: Context[Accessor[str]] = create_context(name="Theme")


@component
def ThemedButton():
    theme = use_context(Theme)  # the accessor the provider passed
    return button("Hi", class_=t"btn-{theme}")


@component
def App():
    theme, set_theme = create_signal("light")
    return Theme(  # value first, then children
        theme,
        div(
            ThemedButton(),
            button("Toggle", on_click=lambda: set_theme("dark" if theme.peek() == "light" else "light")),
        ),
    )

Nested providers for the same context shadow outer ones. Outside a component, use_context still works inside any reactive scope (create_root, an effect, a memo).

See also

  • Concepts: Context
  • Owner: where context values are stored
  • Router: use_params, use_query, and use_base_path are context readers in wybthon.router