Skip to content

docs(react-native): async view model instance creation via useViewModelInstance({ async: true })#797

Draft
mfazekas wants to merge 3 commits into
rive-app:mainfrom
mfazekas:docs/rn-async-useviewmodelinstance
Draft

docs(react-native): async view model instance creation via useViewModelInstance({ async: true })#797
mfazekas wants to merge 3 commits into
rive-app:mainfrom
mfazekas:docs/rn-async-useviewmodelinstance

Conversation

@mfazekas

Copy link
Copy Markdown
Contributor

Documents the async instance-creation API landing in rive-app/rive-nitro-react-native#331: useViewModelInstance(source, { async: true }) returning { instance, isLoading, error }, with the synchronous overloads deprecated.

Updates the data-binding and overview pages to teach async: true as the recommended form (all example snippets migrated), and adds a "Migrating to v0.5.0+" section to the migration guide covering isLoading, the deprecation, useRive().riveViewRef starting as undefined, and the terminal null-source behavior.

Draft until the runtime release ships; the v0.5.0 heading assumes that's the next version number. mintlify broken-links reports the same 33 pre-existing issues as main, none in the touched files.

mfazekas added a commit to rive-app/rive-nitro-react-native that referenced this pull request Jul 13, 2026
…: true }) (#331)

Port of #304 (merged to `feat/rive-ios-experimental`) to `main`.

`useViewModelInstance(source, { async: true })` creates the instance via
the `*Async` runtime APIs off the JS thread and returns `{ instance,
isLoading, error }`. The sync overloads are deprecated per-overload
(they block the JS thread via deprecated runtime APIs); `async: true`
becomes the default in the next major. Overload/deprecation resolution
is pinned with tsd (`yarn typetest`, gated in the CI lint job).

Native side: the `*Async` lookups now hop to the main thread (Android
`riveMainScope`, iOS `Promise.onMain`) since the legacy runtime has no
internal synchronization (the #297 race class), and Android's
`getViewModelInstance()` returns a main-thread-maintained snapshot
instead of traversing the controller off-thread, without blocking JS.

Porting notes:
1. Experimental's `legacy/` sources map onto this branch's flat layout
(`android/src/main`, `ios/`); the `new/`-backend and expo57 harness
changes from #304 don't apply here.
2. `src/hooks/useViewModelInstance.ts` and the ported example files are
taken from the experimental branch (re-run through main's prettier),
which also brings a small pre-#304 improvement: `createInstanceByName`
failures on the sync path now `console.warn` and resolve null instead of
throwing raw native errors.
3. The new e2e harness drops the android-experimental skips
(`RiveFileFactory.getBackend()` doesn't exist here) and adds the
`arbtboards-models-instances.riv` fixture.


Behavioral notes (worth a release-note callout):
1. Android `riveViewRef.getViewModelInstance()` is now eventually
consistent off the main thread: it returns the last main-thread snapshot
and schedules a refresh, instead of the previous unsynchronized live
read (the #297 race). One-shot readers — including the deprecated sync
`useViewModelInstance(riveViewRef)` — can observe `null` where the racy
read happened to catch a late auto-bind; the `async: true` path polls
and is unaffected.
2. `useRive().riveViewRef` now starts as `undefined` (view pending)
instead of `null` (failed/detached), mirroring the `useRiveFile`
convention, and its type widens to `RiveViewRef | null | undefined`.
3. On the sync hook, a `null` source now settles to a terminal `{
instance: null, isLoading: false }` instead of reporting
undefined/loading forever.


Docs: rive-app/rive-docs#797 (draft until this ships).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant