0
# Native View Integration
1
2
Component creation utilities for integrating native UI components into React Native applications with automatic prop handling and cross-platform compatibility.
3
4
## Capabilities
5
6
### requireNativeViewManager Function
7
8
Drop-in replacement for React Native's requireNativeComponent that provides enhanced prop handling and view manager integration.
9
10
```typescript { .api }
11
/**
12
* Create a React component for a native view manager
13
* Drop-in replacement for React Native's requireNativeComponent
14
* @param viewName - Name of the native view manager
15
* @returns React component for the native view
16
*/
17
function requireNativeViewManager<P = any>(viewName: string): React.ComponentType<P>;
18
```
19
20
**Usage Examples:**
21
22
```typescript
23
import { requireNativeViewManager } from "@unimodules/core";
24
import React from "react";
25
26
// Create native view component
27
interface CustomMapViewProps {
28
region: {
29
latitude: number;
30
longitude: number;
31
latitudeDelta: number;
32
longitudeDelta: number;
33
};
34
onRegionChange?: (region: any) => void;
35
showsUserLocation?: boolean;
36
style?: any;
37
}
38
39
const CustomMapView = requireNativeViewManager<CustomMapViewProps>('CustomMapView');
40
41
// Use in React component
42
function MapScreen() {
43
const [region, setRegion] = React.useState({
44
latitude: 37.78825,
45
longitude: -122.4324,
46
latitudeDelta: 0.0922,
47
longitudeDelta: 0.0421,
48
});
49
50
return (
51
<CustomMapView
52
style={{ flex: 1 }}
53
region={region}
54
showsUserLocation={true}
55
onRegionChange={(newRegion) => {
56
setRegion(newRegion);
57
}}
58
/>
59
);
60
}
61
```
62
63
### Native View Props Handling
64
65
The function automatically handles prop separation between React Native standard props and custom view props.
66
67
**Usage Examples:**
68
69
```typescript
70
import { requireNativeViewManager } from "@unimodules/core";
71
72
// Camera view with custom props
73
interface CameraViewProps {
74
// Standard React Native props (handled automatically)
75
style?: any;
76
testID?: string;
77
78
// Custom native view props (passed to native side)
79
cameraType?: 'front' | 'back';
80
flashMode?: 'on' | 'off' | 'auto';
81
quality?: number;
82
onCameraReady?: () => void;
83
onPictureTaken?: (data: { uri: string }) => void;
84
}
85
86
const CameraView = requireNativeViewManager<CameraViewProps>('ExpoCameraView');
87
88
function CameraScreen() {
89
return (
90
<CameraView
91
style={{ flex: 1 }}
92
testID="camera-view"
93
cameraType="back"
94
flashMode="auto"
95
quality={0.8}
96
onCameraReady={() => {
97
console.log('Camera is ready');
98
}}
99
onPictureTaken={(data) => {
100
console.log('Picture taken:', data.uri);
101
}}
102
/>
103
);
104
}
105
```
106
107
### Multiple Native Views
108
109
Create multiple native view components for different native managers.
110
111
**Usage Examples:**
112
113
```typescript
114
import { requireNativeViewManager } from "@unimodules/core";
115
116
// Different native views
117
const VideoView = requireNativeViewManager<{
118
source: { uri: string };
119
shouldPlay?: boolean;
120
isLooping?: boolean;
121
volume?: number;
122
onPlaybackStatusUpdate?: (status: any) => void;
123
}>('ExpoVideoView');
124
125
const WebView = requireNativeViewManager<{
126
source: { uri: string };
127
onLoadStart?: () => void;
128
onLoadEnd?: () => void;
129
onError?: (error: any) => void;
130
}>('ExpoWebView');
131
132
const BlurView = requireNativeViewManager<{
133
intensity?: number;
134
tint?: 'light' | 'dark' | 'default';
135
}>('ExpoBlurView');
136
137
// Use multiple views
138
function MediaScreen() {
139
return (
140
<View style={{ flex: 1 }}>
141
<VideoView
142
style={{ height: 200 }}
143
source={{ uri: 'https://example.com/video.mp4' }}
144
shouldPlay={true}
145
volume={0.8}
146
/>
147
148
<WebView
149
style={{ flex: 1 }}
150
source={{ uri: 'https://example.com' }}
151
onLoadEnd={() => console.log('Web page loaded')}
152
/>
153
154
<BlurView
155
style={{ position: 'absolute', top: 0, left: 0, right: 0, height: 100 }}
156
intensity={50}
157
tint="light"
158
/>
159
</View>
160
);
161
}
162
```
163
164
## Advanced Usage
165
166
### Development Environment Checks
167
168
The function includes development-time validation to ensure view managers are properly registered.
169
170
**Usage Examples:**
171
172
```typescript
173
import { requireNativeViewManager } from "@unimodules/core";
174
175
// This will warn in development if 'MyCustomView' is not registered
176
const MyCustomView = requireNativeViewManager('MyCustomView');
177
178
// Handle potential missing view managers gracefully
179
function createOptionalNativeView(viewName: string) {
180
try {
181
return requireNativeViewManager(viewName);
182
} catch (error) {
183
console.warn(`Native view ${viewName} not available:`, error.message);
184
return null;
185
}
186
}
187
188
// Conditional native view usage
189
const OptionalView = createOptionalNativeView('OptionalNativeView');
190
191
function ConditionalViewScreen() {
192
if (OptionalView) {
193
return <OptionalView style={{ flex: 1 }} />;
194
} else {
195
return <View style={{ flex: 1 }}><Text>Native view not available</Text></View>;
196
}
197
}
198
```
199
200
### Native View Ref Handling
201
202
Working with refs to access native view methods.
203
204
**Usage Examples:**
205
206
```typescript
207
import { requireNativeViewManager } from "@unimodules/core";
208
import React, { useRef } from "react";
209
210
interface CameraViewRef {
211
takePictureAsync: (options?: any) => Promise<{ uri: string }>;
212
recordAsync: (options?: any) => Promise<{ uri: string }>;
213
stopRecording: () => void;
214
}
215
216
const CameraView = requireNativeViewManager<{
217
ref?: React.Ref<CameraViewRef>;
218
cameraType?: 'front' | 'back';
219
}>('ExpoCameraView');
220
221
function CameraWithControls() {
222
const cameraRef = useRef<CameraViewRef>(null);
223
224
const takePicture = async () => {
225
if (cameraRef.current) {
226
try {
227
const result = await cameraRef.current.takePictureAsync({
228
quality: 0.8,
229
base64: false
230
});
231
console.log('Picture saved to:', result.uri);
232
} catch (error) {
233
console.error('Failed to take picture:', error);
234
}
235
}
236
};
237
238
const startRecording = async () => {
239
if (cameraRef.current) {
240
try {
241
const result = await cameraRef.current.recordAsync({
242
maxDuration: 10, // 10 seconds
243
quality: 'high'
244
});
245
console.log('Video saved to:', result.uri);
246
} catch (error) {
247
console.error('Failed to record video:', error);
248
}
249
}
250
};
251
252
return (
253
<View style={{ flex: 1 }}>
254
<CameraView
255
ref={cameraRef}
256
style={{ flex: 1 }}
257
cameraType="back"
258
/>
259
260
<View style={{ flexDirection: 'row', justifyContent: 'space-around', padding: 20 }}>
261
<Button title="Take Picture" onPress={takePicture} />
262
<Button title="Record Video" onPress={startRecording} />
263
</View>
264
</View>
265
);
266
}
267
```
268
269
### Custom Prop Validation
270
271
Add runtime prop validation for native views.
272
273
**Usage Examples:**
274
275
```typescript
276
import { requireNativeViewManager } from "@unimodules/core";
277
import React from "react";
278
279
// Create wrapper with prop validation
280
function createValidatedNativeView<P>(viewName: string, validator?: (props: P) => void) {
281
const NativeView = requireNativeViewManager<P>(viewName);
282
283
return React.forwardRef<any, P>((props, ref) => {
284
if (validator) {
285
validator(props);
286
}
287
return <NativeView ref={ref} {...props} />;
288
});
289
}
290
291
// Example with validation
292
interface MapViewProps {
293
region: {
294
latitude: number;
295
longitude: number;
296
latitudeDelta: number;
297
longitudeDelta: number;
298
};
299
zoom?: number;
300
}
301
302
const MapView = createValidatedNativeView<MapViewProps>('MapView', (props) => {
303
if (props.zoom && (props.zoom < 0 || props.zoom > 20)) {
304
throw new Error('Zoom level must be between 0 and 20');
305
}
306
307
if (Math.abs(props.region.latitude) > 90) {
308
throw new Error('Latitude must be between -90 and 90');
309
}
310
311
if (Math.abs(props.region.longitude) > 180) {
312
throw new Error('Longitude must be between -180 and 180');
313
}
314
});
315
```
316
317
### Platform-Specific Native Views
318
319
Handle platform-specific view managers.
320
321
**Usage Examples:**
322
323
```typescript
324
import { requireNativeViewManager, Platform } from "@unimodules/core";
325
326
// Platform-specific view creation
327
function createPlatformNativeView(viewNames: { ios?: string; android?: string; web?: string }) {
328
const viewName = Platform.select(viewNames);
329
330
if (!viewName) {
331
console.warn('No native view available for current platform');
332
return null;
333
}
334
335
return requireNativeViewManager(viewName);
336
}
337
338
// Platform-specific implementation
339
const PlatformSpecificView = createPlatformNativeView({
340
ios: 'IOSSpecificView',
341
android: 'AndroidSpecificView',
342
web: 'WebSpecificView'
343
});
344
345
function PlatformViewScreen() {
346
if (!PlatformSpecificView) {
347
return <Text>Platform-specific view not available</Text>;
348
}
349
350
return (
351
<PlatformSpecificView
352
style={{ flex: 1 }}
353
// Platform-specific props will be different
354
{...Platform.select({
355
ios: { iosSpecificProp: true },
356
android: { androidSpecificProp: 'value' },
357
web: { webSpecificProp: 42 }
358
})}
359
/>
360
);
361
}
362
```
363
364
## Types
365
366
```typescript { .api }
367
type NativeViewComponent<P = any> = React.ComponentType<P>;
368
369
interface NativeViewManagerAdapter {
370
<P = any>(viewName: string): NativeViewComponent<P>;
371
}
372
373
interface ViewManagerConfig {
374
viewManagersNames: string[];
375
}
376
377
interface NativeExpoComponentProps {
378
proxiedProperties: object;
379
}
380
```