Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions resources/views/docs/mobile/4/digging-deeper/lifecycle-hooks.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,48 @@ class Dashboard extends NativeComponent
Override `placeholder()` to customize the loading frame; the default is a centered activity indicator wrapped in
the screen's layout chrome.

## Observing the lifecycle from outside

The hooks above are yours to override, which makes them the wrong place for anything cross-cutting. Put
analytics, telemetry, or crash breadcrumbs in a base class's `mount()` and any screen that defines its own
`mount()` silently replaces it — so the observer goes quiet on exactly the screens with the most logic in them.

For that, the router dispatches ordinary Laravel events alongside each hook:

| Event | Fires |
|-------|-------|
| `ScreenMounted` | after a freshly pushed screen's `mount()` |
| `ScreenResumed` | after `onResume()`, when the user returns to a screen already on the stack |
| `ScreenUnmounted` | after `unmount()`, as the screen leaves the stack |

Each carries the component class and the screen's uri, and you listen for them anywhere you'd listen for a
Laravel event — a service provider, an `AppServiceProvider` boot method, a dedicated subscriber:

```php
use Illuminate\Support\Facades\Event;
use Native\Mobile\Events\Screen\ScreenMounted;

Event::listen(ScreenMounted::class, function (ScreenMounted $event) {
Analytics::screen($event->component, $event->uri);
});
```

These fire *around* your hooks rather than instead of them — overriding `mount()` changes nothing about when
they arrive, which is the whole point.

Two things worth knowing. A listener that throws is caught and logged rather than propagated: an observer
should not be able to take the navigation loop down with it, so check your logs if one seems not to run. And
restoring a preloaded stack after a hot reload stays quiet — those screens are being restored, not navigated
to.

<aside>

These are app-wide Laravel events, not the component-targeted native events on the
[Events](../the-basics/events) page. Use `#[On]` when a screen needs to react to something; use these when
something outside the screens needs to know what the user is doing.

</aside>

## Related

Beyond the lifecycle, screens react to the outside world through a few attributes:
Expand Down
4 changes: 4 additions & 0 deletions resources/views/docs/mobile/4/the-basics/events.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ Native events originate on the device side and are delivered to whichever screen
events an async native call resolves with. Because delivery targets the live screen, a listener only fires while
its screen is on the stack.

That last part is also the limit of this page. If something outside your screens needs to follow what the user
is doing — analytics, telemetry, crash breadcrumbs — listen for the app-wide
[screen lifecycle events](../digging-deeper/lifecycle-hooks#observing-the-lifecycle-from-outside) instead.

<aside>

You can drive events in tests without a device — `emitNative(Event::class, [...])` delivers one straight to the
Expand Down