July 30, 2026 — The unofficial Laracon US Day 3. Get your ticket to The Vibes

You're viewing pre-release documentation — version 4.x is in beta

Features, APIs and behaviour may change before the stable release. View the stable version (3.x)

Reactivity


Overview#

SuperNative screens re-render when their state changes — you rarely rebuild the UI by hand. Two tools make state declarative: computed properties for values derived from other state, and polling for state that needs to refresh on a timer.

Computed properties#

Mark a method #[Computed] and read it as a property. The result is memoized for the frame and recomputed whenever state changes, so you never cache derived values by hand or worry about them going stale.

Copied!
use Native\Mobile\Attributes\Computed;
 
class CartScreen extends NativeComponent
{
public array $items = [];
 
#[Computed]
public function total(): float
{
return collect($this->items)->sum('price');
}
}

Access it as $this->total (no parentheses) in PHP, or {{ $this->total }} in the view:

Copied!
<native:text>Total: {{ $this->total }}</native:text>

The value is cached per render and the whole computed cache is cleared on any state change (every model sync drops it), so total recomputes exactly when items changes — and never more often.

Persisting across frames#

By default a computed value is recomputed each frame. For an expensive result that only depends on inputs which change rarely, pass persist: true to keep it across frames until the next state change:

Copied!
#[Computed(persist: true)]
public function report(): array
{
return $this->crunchExpensiveReport(); // survives re-renders until state changes
}

Polling#

Refresh state on an interval with #[Poll]. On a method, it runs the method then re-renders; the argument is the interval in milliseconds (default 2000):

Copied!
use Native\Mobile\Attributes\Poll;
 
#[Poll(5000)] // every 5 seconds
public function refreshFeed(): void
{
$this->posts = Post::latest()->take(20)->get()->all();
}

On the class, #[Poll] just re-renders on the interval — handy when the UI reflects time (a countdown, a "last updated" label) without any method to run:

Copied!
#[Poll(1000)]
class ClockScreen extends NativeComponent { /* re-renders every second */ }

Polling from Blade#

You can also drive a re-render from the view with native:poll — useful for a single element that needs to tick without wiring a method:

Copied!
<native:text native:poll="1s">{{ now()->format('g:i:s A') }}</native:text>

Accepted forms: native:poll (default 2s), native:poll="500ms" / native:poll="1s" (value), and native:poll.2s (modifier).