reactivity
wybthon.reactivity¶
Signal-based reactive primitives and async Resource helper.
Computation
¶
Reactive computation that tracks Signals and re-runs when they change.
Resource
¶
Bases: Generic[R]
Async resource wrapper with Signals for data, error, and loading.
Use reload() to (re)fetch, cancel() to cancel the in-flight request.
Optionally accepts a source getter; when the source signal changes the
resource automatically refetches.
Signal
¶
Bases: Generic[T]
Mutable container that notifies subscribed computations on changes.
batch()
¶
Batch signal updates within the returned context manager.
computed(fn)
¶
Create a computed value that derives from other signals.
create_effect(fn)
¶
Create an auto-tracking reactive effect.
The effect runs immediately and re-runs whenever any signal read
inside fn changes. on_cleanup may be called inside fn to
register per-run cleanup (runs before re-execution and on disposal).
If fn accepts a positional parameter, the previous return value
is passed on each re-execution (None on the first run), matching
SolidJS createEffect(prev => ...)::
create_effect(lambda prev: (print("was", prev), count())[1])
Inside a component, the effect is automatically disposed on unmount.
create_memo(fn)
¶
Create an auto-tracking computed value. Returns a getter function.
Re-computes only when signals read inside fn change. Inside a component, the underlying computation is disposed on unmount.
Example::
doubled = create_memo(lambda: count() * 2)
print(doubled()) # reactive read
create_resource(source_or_fetcher, fetcher=None)
¶
Create an async Resource with loading/error states and cancellation.
Can be called two ways:
create_resource(fetcher)-- simple fetcher, no source signal.create_resource(source, fetcher)-- refetches automatically when the source getter's return value changes.
The fetcher should be an async function returning the data value.
If it accepts a signal keyword argument, an AbortSignal will be
passed for cancellation support when available.
create_root(fn)
¶
Run fn with an independent reactive root.
fn receives a dispose callback that tears down all effects
created inside the root::
result = create_root(lambda dispose: ...)
create_signal(value)
¶
Create a reactive signal. Returns (getter, setter).
Works inside or outside components. Inside a stateful component the signal is captured by the render function's closure and persists naturally (no cursor system needed).
Example::
count, set_count = create_signal(0)
print(count()) # 0
set_count(5)
print(count()) # 5
effect(fn)
¶
Run a reactive effect and return its computation handle.
get_props()
¶
Return a reactive getter for the current component's props.
Useful in stateful components that need to react to parent prop changes::
props = get_props()
create_effect(lambda: print("query changed:", props()["query"]))
merge_props(*sources)
¶
Merge multiple prop dicts. Later sources win on conflict.
Example::
defaults = {"size": "md", "variant": "solid"}
final = merge_props(defaults, props)
on(deps, fn, defer=False)
¶
Create an effect with explicit dependencies.
deps is a single getter or a list of getters. fn receives the
current value(s) as positional arguments. Only the listed deps are
tracked; the body of fn is run inside untrack.
When defer is True the effect skips the first execution
(useful for reacting only to changes, not the initial value).
Example::
on(count, lambda v: print("count is now", v))
on_cleanup(fn)
¶
Register a cleanup callback.
- Inside
create_effect: runs before each re-execution and on disposal. - Inside a component's setup phase: runs when the component unmounts.
on_effect_cleanup(comp, fn)
¶
Register a cleanup callback to run when a computation is disposed.
on_mount(fn)
¶
Register a callback to run once after the component mounts.
Must be called during a component's setup phase (the body of a
@component function, before the return).
signal(value)
¶
Create a new Signal with the given initial value.
split_props(props, *key_groups)
¶
Split a props dict into groups by key name, plus a rest dict.
Returns (group1, group2, ..., rest) where rest contains keys
not claimed by any group.
Example::
local, rest = split_props(props, ["class", "style"])
untrack(fn)
¶
Run fn without tracking any signal reads.
Useful inside effects when you need to read a signal without creating a dependency::
create_effect(lambda: print("a changed:", a(), "b is:", untrack(b)))
Public API¶
Signals-first API (recommended)¶
create_signal(value) -> (getter, setter)create_effect(fn) -> Computation— supports previous value:create_effect(lambda prev: ...)create_memo(fn) -> getteron_mount(fn)— run after first renderon_cleanup(fn)— run on unmount or before effect re-executionbatch() -> context manager
Resources¶
create_resource(fetcher) -> Resourcecreate_resource(source, fetcher) -> Resource— refetches when source changes
Reactive utilities¶
untrack(fn)— run without tracking signal readson(deps, fn, defer=False)— effect with explicit depscreate_root(fn)— independent reactive scopemerge_props(*sources)— merge prop dictssplit_props(props, *key_groups)— split props by key name
Type hints are provided for all public functions and classes.