Mapping JavaScript Props to Native Views
React Native bridges JS props to native views via annotated setters. Use it when wrapping platform views like maps or video players. The footgun is a missing annotation: the prop crosses the bridge but native never receives it, causing silent failures and…
Why it exists
React Native renders native platform views, not DOM nodes. When you need to reuse a platform view that does not exist in the core framework, such as a Mapbox map or a hardware barcode scanner, you must create a native UI component. The problem is that JavaScript and native runtimes are separate, so there is no automatic way for a JS prop like zoomLevel to reach the underlying native map object. Exposing properties solves this by declaring a typed bridge between the two runtimes.
The mental model
Think of the native view as a remote device controlled by a typed command bus. JavaScript sends declarative state updates across the bridge, and the native side translates each update into an imperative setter call on the view. The native developer acts like an electrician wiring labeled switches: each switch is a prop name, and flipping it on the JS side must connect to exactly one native terminal or nothing happens.
How it works
On Android, you annotate a setter method with @ReactProp and specify the name and default type. On iOS, you use the RCT_CUSTOM_VIEW_PROPERTY macro inside a category or subclass to map a prop name to a setter block. React Native's shadow tree diffing detects prop changes, serializes them, and dispatches them to the native module queue. The native view manager receives the payload and invokes the matching setter. Type mismatches, such as sending a string where a float is expected, typically crash at the bridge boundary rather than in JavaScript.
When to use it
Use this pattern when you are wrapping a heavyweight platform view that must stay native for performance or SDK reasons, and you want to control its configuration or appearance from React. Examples include setting the tint color on a custom video player, passing a region object to a map, or toggling flash mode on a camera preview.
When not to use it
Do not use exposed props for high-frequency updates that exceed the bridge throughput, such as driving a native animation frame-by-frame from JavaScript. Avoid them for fire-and-forget commands like play or pause that are better modeled as imperative methods via ref commands or native modules. Also skip this if a purely JavaScript implementation already meets your needs, since native components add build complexity and platform-specific maintenance.
One canonical example
Imagine wrapping a native heatmap view. You expose a dataPoints prop. On Android, you write @ReactProp(name = "dataPoints") public void setDataPoints(HeatmapView view, ReadableArray points) and parse the array into native LatLng objects. On iOS, you write RCT_CUSTOM_VIEW_PROPERTY(dataPoints, HeatmapView) { view.points = [RCTConvert NSArray:json]; }. When the JS component receives new survey results, it passes a new array, the bridge diff picks it up, and the native view redraws the heatmap without a full re-mount. If you forget the annotation, the array arrives on the native side but the view manager has no handler registered, so the update is silently dropped and the heatmap stays blank.
Interview question
You are deciding whether to control a native view feature via a bridged prop or an imperative command. Which situation favors an imperative command?
- a.Sending a play or pause signal to a native video player as a user interactionCorrect
- b.Passing an initial region object to configure a native map on mount
- c.Feeding new survey results into a native heatmap view via a data array
- d.Setting the tint color of a custom video player from a React theme
Why? this is the answer
The card explicitly warns against using bridged props for fire-and-forget commands like play or pause, which are better modeled as imperative methods via refs or native modules. Passing a region object to a map is a valid prop use case because it represents persistent declarative configuration.
Just read this? Test yourself on what you have been reading.
- #react-native
- #native-modules
- #mobile
- #bridge
- #ui-components
Put your scrolling time to good use
Learn one idea, try a quiz and save useful cards for revision. Tezvyn makes it easy to learn and stay current in your tech field, a few minutes at a time.
The iPhone app is on the way
We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.
Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.
We are hiring for this. Open roles that interview on react-native — each one lists the topics its interview covers.
See open roles