Passing props
How props cross the threaded boundary, what's serializable, and the recommended id-plus-store pattern.
Props are serialized by the main runtime and passed to the threaded surface as JSON when the surface mounts. They are initial props: changing them later stops the native surface and remounts it with the new values, losing all threaded-side state. Keep them small and stable.
<ThreadedScreen
component={ConversationScreen}
props={{
conversationId: 'release-room',
initialMessageCount: 96,
participants: 'Ava, Noah, Mia',
}}
runtimeName="conversation-release-room-runtime"
/>Inside the threaded component, read props normally:
type ConversationScreenProps = {
conversationId: string;
initialMessageCount: number;
participants: string;
runtimeName?: string;
};
export const ConversationScreen = threadedComponent<ConversationScreenProps>(
'ConversationScreen',
function ConversationScreen(props) {
return <ConversationRoute {...props} />;
},
);Rules
- Props must be JSON-serializable.
- Do not pass functions, class instances, refs, native handles, or cyclic objects.
- Prefer ids, cursors, and config values over large datasets.
- Use
@react-native-runtimes/statefor anything that changes after mount. - Keep
runtimeNamestable for a logical owner, such as one runtime per conversation.
Changing a prop remounts the surface
Props are mount-time only. When any prop changes, the native surface is
stopped and recreated with the new values — the threaded component loses all
of its state (scroll position, inputs, useState). Data that changes over
time must flow through a shared path, not
props.
Recommended pattern
Pass identity through props, then load or subscribe to the real data inside the threaded runtime:
<ThreadedScreen
component={ConversationScreen}
props={{ conversationId }}
runtimeName={`conversation-${conversationId}-runtime`}
/>function ConversationRoute({ conversationId }: { conversationId: string }) {
const messages = messagesStore
.path<Message[]>(['conversations', conversationId])
.use(value => value ?? []);
return <MessageList messages={messages} />;
}The main runtime never touches the messages array. It only forwards a string id; the threaded runtime owns reading, rendering, and reacting to the data.
What's safe to pass
| Prop shape | Pass as prop? | Notes |
|---|---|---|
string, number, boolean, null | ✅ | Always safe. |
string[], number[] | ✅ | Fine for small arrays (under ~1 KB). |
{ id, name, count } | ✅ | Plain objects of primitives. |
Message[] (large list) | 🚫 | Use a shared path. |
Date, Map, Set | 🚫 | Not JSON; pass as ISO strings / arrays. |
| Functions, refs, class instances | 🚫 | Cannot cross the boundary. |