CtrlK
CommunityDocumentationLog inGet started
Tessl Logo

tessl/npm-react-native

A framework for building native apps using React

Overall
score

100%

Evaluation100%

1.06x

Agent success when using this tile

Overview
Eval results
Files

native-bridge.mddocs/

React Native Native Bridge APIs

React Native provides powerful APIs for bridging between JavaScript and native code, enabling access to platform-specific functionality and custom native modules.

Installation

npm install react-native

Native Module Access

NativeModules

Access all registered native modules and their exposed methods from JavaScript.

// ESM
import {NativeModules} from 'react-native';

// CommonJS
const {NativeModules} = require('react-native');

// Access built-in native modules
const {
  StatusBarManager,
  DeviceInfo,
  NetworkingIOS,
  PlatformConstants,
  UIManager,
} = NativeModules;

// Example: Using StatusBarManager (iOS)
if (Platform.OS === 'ios' && StatusBarManager) {
  StatusBarManager.getHeight((statusBarFrameData) => {
    console.log('Status bar height:', statusBarFrameData.height);
  });
}

// Access custom native modules
const {MyCustomModule} = NativeModules;

if (MyCustomModule) {
  // Call native method
  MyCustomModule.doSomething('parameter', (error, result) => {
    if (error) {
      console.error('Native module error:', error);
    } else {
      console.log('Native module result:', result);
    }
  });
  
  // Promise-based native method
  MyCustomModule.asyncOperation('data')
    .then(result => console.log('Async result:', result))
    .catch(error => console.error('Async error:', error));
}

// Check if native module exists
function useNativeModule(moduleName) {
  const module = NativeModules[moduleName];
  
  if (!module) {
    console.warn(`Native module ${moduleName} is not available`);
    return null;
  }
  
  return module;
}

// Safe native module usage
function SafeNativeModuleComponent() {
  const customModule = useNativeModule('MyCustomModule');
  
  const handleNativeCall = async () => {
    if (!customModule) {
      Alert.alert('Error', 'Native module not available');
      return;
    }
    
    try {
      const result = await customModule.performOperation();
      console.log('Operation completed:', result);
    } catch (error) {
      console.error('Native operation failed:', error);
      Alert.alert('Error', 'Operation failed');
    }
  };
  
  return (
    <Button 
      title="Call Native Module" 
      onPress={handleNativeCall}
      disabled={!customModule}
    />
  );
}

// Batch native operations
async function batchNativeOperations() {
  const {FileManager, DatabaseModule} = NativeModules;
  
  if (!FileManager || !DatabaseModule) {
    throw new Error('Required native modules not available');
  }
  
  try {
    // Parallel native operations
    const [fileResult, dbResult] = await Promise.all([
      FileManager.readFile('/path/to/file'),
      DatabaseModule.query('SELECT * FROM users'),
    ]);
    
    return {fileResult, dbResult};
  } catch (error) {
    console.error('Batch operations failed:', error);
    throw error;
  }
}

// Native module constants
function getNativeConstants() {
  const constants = {};
  
  Object.keys(NativeModules).forEach(moduleName => {
    const module = NativeModules[moduleName];
    if (module && module.getConstants) {
      constants[moduleName] = module.getConstants();
    }
  });
  
  return constants;
}

// Example custom native module interface
const CameraModule = NativeModules.CameraModule;

const cameraAPI = {
  // Check permissions
  hasPermission: () => CameraModule?.hasPermission() || Promise.resolve(false),
  
  // Request permissions
  requestPermission: () => CameraModule?.requestPermission() || Promise.reject('Not available'),
  
  // Take photo
  capturePhoto: (options = {}) => {
    if (!CameraModule) {
      return Promise.reject('Camera module not available');
    }
    
    return CameraModule.capturePhoto({
      quality: 0.8,
      format: 'jpeg',
      ...options,
    });
  },
  
  // Record video
  recordVideo: (options = {}) => {
    if (!CameraModule) {
      return Promise.reject('Camera module not available');
    }
    
    return CameraModule.recordVideo({
      maxDuration: 60,
      quality: 'high',
      ...options,
    });
  },
};

// Hook for native module
function useCameraModule() {
  const [hasPermission, setHasPermission] = useState(false);
  const [isLoading, setIsLoading] = useState(false);
  
  useEffect(() => {
    checkPermission();
  }, []);
  
  const checkPermission = async () => {
    try {
      const permission = await cameraAPI.hasPermission();
      setHasPermission(permission);
    } catch (error) {
      console.error('Permission check failed:', error);
    }
  };
  
  const requestPermission = async () => {
    setIsLoading(true);
    try {
      const granted = await cameraAPI.requestPermission();
      setHasPermission(granted);
      return granted;
    } catch (error) {
      console.error('Permission request failed:', error);
      return false;
    } finally {
      setIsLoading(false);
    }
  };
  
  const capturePhoto = async (options) => {
    if (!hasPermission) {
      const granted = await requestPermission();
      if (!granted) throw new Error('Camera permission required');
    }
    
    return cameraAPI.capturePhoto(options);
  };
  
  return {
    hasPermission,
    isLoading,
    requestPermission,
    capturePhoto,
    recordVideo: cameraAPI.recordVideo,
  };
}
interface NativeModulesStatic {
  [key: string]: any;
}

// Common native module patterns
interface NativeModuleBase {
  getConstants?(): {[key: string]: any};
  addListener?(eventType: string): void;
  removeListeners?(count: number): void;
}

// Example native module interfaces
interface FileSystemModule extends NativeModuleBase {
  readFile(path: string): Promise<string>;
  writeFile(path: string, content: string): Promise<void>;
  deleteFile(path: string): Promise<void>;
  exists(path: string): Promise<boolean>;
  mkdir(path: string): Promise<void>;
  readdir(path: string): Promise<string[]>;
}

interface DatabaseModule extends NativeModuleBase {
  open(path: string): Promise<void>;
  close(): Promise<void>;
  query(sql: string, params?: any[]): Promise<any[]>;
  execute(sql: string, params?: any[]): Promise<void>;
}

interface BluetoothModule extends NativeModuleBase {
  isEnabled(): Promise<boolean>;
  enable(): Promise<void>;
  scan(duration?: number): Promise<Device[]>;
  connect(deviceId: string): Promise<void>;
  disconnect(deviceId: string): Promise<void>;
  sendData(data: string): Promise<void>;
}

TurboModuleRegistry

Access the new TurboModule system for improved performance and type safety.

import {TurboModuleRegistry} from 'react-native';

// Get TurboModule
const MyTurboModule = TurboModuleRegistry.get('MyTurboModule');

// TurboModule with type safety (requires native implementation)
function useTurboModule(moduleName) {
  const [module, setModule] = useState(null);
  
  useEffect(() => {
    try {
      const turboModule = TurboModuleRegistry.get(moduleName);
      setModule(turboModule);
    } catch (error) {
      console.warn(`TurboModule ${moduleName} not found:`, error);
    }
  }, [moduleName]);
  
  return module;
}

// Example TurboModule usage
function TurboModuleComponent() {
  const calculator = useTurboModule('CalculatorTurboModule');
  
  const [result, setResult] = useState(0);
  
  const performCalculation = async () => {
    if (!calculator) {
      Alert.alert('Error', 'Calculator module not available');
      return;
    }
    
    try {
      // TurboModule methods are synchronous by default
      const sum = calculator.add(10, 20);
      const product = calculator.multiply(5, 4);
      
      setResult(sum + product);
    } catch (error) {
      console.error('Calculation failed:', error);
    }
  };
  
  return (
    <View>
      <Text>Result: {result}</Text>
      <Button title="Calculate" onPress={performCalculation} />
    </View>
  );
}

// TurboModule with async operations
function AsyncTurboModuleExample() {
  const networkModule = useTurboModule('NetworkTurboModule');
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(false);
  
  const fetchData = async () => {
    if (!networkModule) return;
    
    setLoading(true);
    try {
      // Async TurboModule method
      const response = await networkModule.fetchData('https://api.example.com/data');
      setData(response);
    } catch (error) {
      console.error('Fetch failed:', error);
    } finally {
      setLoading(false);
    }
  };
  
  return (
    <View>
      {loading && <ActivityIndicator />}
      {data && <Text>{JSON.stringify(data, null, 2)}</Text>}
      <Button title="Fetch Data" onPress={fetchData} />
    </View>
  );
}

// Check TurboModule availability
function checkTurboModuleSupport() {
  try {
    // Check if TurboModule system is available
    const testModule = TurboModuleRegistry.get('TestModule');
    return true;
  } catch (error) {
    console.log('TurboModule system not available');
    return false;
  }
}

// Fallback pattern for TurboModules
function useTurboModuleWithFallback(turboModuleName, fallbackModuleName) {
  const [module, setModule] = useState(null);
  const [isTurbo, setIsTurbo] = useState(false);
  
  useEffect(() => {
    try {
      // Try TurboModule first
      const turboModule = TurboModuleRegistry.get(turboModuleName);
      setModule(turboModule);
      setIsTurbo(true);
    } catch (error) {
      // Fallback to regular NativeModule
      const fallbackModule = NativeModules[fallbackModuleName];
      if (fallbackModule) {
        setModule(fallbackModule);
        setIsTurbo(false);
      }
    }
  }, [turboModuleName, fallbackModuleName]);
  
  return {module, isTurbo};
}
interface TurboModuleRegistryStatic {
  get<T extends TurboModule>(name: string): T | null;
  getEnforcing<T extends TurboModule>(name: string): T;
}

interface TurboModule {
  getConstants?(): {[key: string]: any};
}

// Example TurboModule interface
interface CalculatorTurboModule extends TurboModule {
  add(a: number, b: number): number;
  subtract(a: number, b: number): number;
  multiply(a: number, b: number): number;
  divide(a: number, b: number): number;
  power(base: number, exponent: number): Promise<number>;
}

interface NetworkTurboModule extends TurboModule {
  fetchData(url: string): Promise<any>;
  uploadFile(path: string, url: string): Promise<{success: boolean; response: any}>;
  downloadFile(url: string, destination: string): Promise<string>;
}

Event Communication

NativeEventEmitter

Create event emitters for communication between JavaScript and native code.

import {NativeEventEmitter, NativeModules} from 'react-native';

// Create event emitter for native module
const {MyNativeModule} = NativeModules;
const myModuleEmitter = MyNativeModule ? new NativeEventEmitter(MyNativeModule) : null;

// Listen to native events
function useNativeEvents() {
  useEffect(() => {
    if (!myModuleEmitter) return;
    
    // Add event listeners
    const subscription1 = myModuleEmitter.addListener('onDataReceived', (data) => {
      console.log('Data received from native:', data);
    });
    
    const subscription2 = myModuleEmitter.addListener('onError', (error) => {
      console.error('Native error:', error);
    });
    
    const subscription3 = myModuleEmitter.addListener('onStatusChanged', (status) => {
      console.log('Status changed:', status);
    });
    
    // Cleanup listeners
    return () => {
      subscription1.remove();
      subscription2.remove();
      subscription3.remove();
    };
  }, []);
}

// Bluetooth event example
function BluetoothEventManager() {
  const {BluetoothModule} = NativeModules;
  const bluetoothEmitter = BluetoothModule ? new NativeEventEmitter(BluetoothModule) : null;
  
  const [devices, setDevices] = useState([]);
  const [connectionStatus, setConnectionStatus] = useState('disconnected');
  
  useEffect(() => {
    if (!bluetoothEmitter) return;
    
    const deviceFoundSubscription = bluetoothEmitter.addListener(
      'deviceFound', 
      (device) => {
        setDevices(prevDevices => [...prevDevices, device]);
      }
    );
    
    const connectionSubscription = bluetoothEmitter.addListener(
      'connectionStatusChanged',
      (status) => {
        setConnectionStatus(status);
      }
    );
    
    const dataSubscription = bluetoothEmitter.addListener(
      'dataReceived',
      (data) => {
        console.log('Bluetooth data:', data);
      }
    );
    
    return () => {
      deviceFoundSubscription.remove();
      connectionSubscription.remove();
      dataSubscription.remove();
    };
  }, [bluetoothEmitter]);
  
  const startScan = () => {
    if (BluetoothModule) {
      BluetoothModule.startScan();
    }
  };
  
  const connectToDevice = (deviceId) => {
    if (BluetoothModule) {
      BluetoothModule.connect(deviceId);
    }
  };
  
  return (
    <View>
      <Text>Connection Status: {connectionStatus}</Text>
      
      <Button title="Start Scan" onPress={startScan} />
      
      <FlatList
        data={devices}
        keyExtractor={item => item.id}
        renderItem={({item}) => (
          <TouchableOpacity onPress={() => connectToDevice(item.id)}>
            <Text>{item.name} - {item.id}</Text>
          </TouchableOpacity>
        )}
      />
    </View>
  );
}

// Location event emitter
function LocationTracker() {
  const {LocationModule} = NativeModules;
  const locationEmitter = LocationModule ? new NativeEventEmitter(LocationModule) : null;
  
  const [location, setLocation] = useState(null);
  const [isTracking, setIsTracking] = useState(false);
  
  useEffect(() => {
    if (!locationEmitter) return;
    
    const locationSubscription = locationEmitter.addListener(
      'locationUpdate',
      (newLocation) => {
        setLocation(newLocation);
      }
    );
    
    const errorSubscription = locationEmitter.addListener(
      'locationError',
      (error) => {
        console.error('Location error:', error);
        Alert.alert('Location Error', error.message);
      }
    );
    
    return () => {
      locationSubscription.remove();
      errorSubscription.remove();
    };
  }, [locationEmitter]);
  
  const startTracking = () => {
    if (LocationModule) {
      LocationModule.startLocationUpdates();
      setIsTracking(true);
    }
  };
  
  const stopTracking = () => {
    if (LocationModule) {
      LocationModule.stopLocationUpdates();
      setIsTracking(false);
    }
  };
  
  return (
    <View>
      {location && (
        <Text>
          Location: {location.latitude}, {location.longitude}
        </Text>
      )}
      
      <Button
        title={isTracking ? 'Stop Tracking' : 'Start Tracking'}
        onPress={isTracking ? stopTracking : startTracking}
      />
    </View>
  );
}

// Generic event emitter hook
function useNativeEventEmitter(nativeModule, events = []) {
  const [emitter, setEmitter] = useState(null);
  
  useEffect(() => {
    if (nativeModule) {
      const eventEmitter = new NativeEventEmitter(nativeModule);
      setEmitter(eventEmitter);
      return () => {
        // Emitter cleanup is handled by individual subscriptions
      };
    }
  }, [nativeModule]);
  
  useEffect(() => {
    if (!emitter || events.length === 0) return;
    
    const subscriptions = events.map(({eventName, callback}) => 
      emitter.addListener(eventName, callback)
    );
    
    return () => {
      subscriptions.forEach(subscription => subscription.remove());
    };
  }, [emitter, events]);
  
  return emitter;
}

// Usage with generic hook
function GenericNativeComponent() {
  const {SensorModule} = NativeModules;
  const [sensorData, setSensorData] = useState({});
  
  useNativeEventEmitter(SensorModule, [
    {
      eventName: 'accelerometerData',
      callback: (data) => setSensorData(prev => ({...prev, accelerometer: data})),
    },
    {
      eventName: 'gyroscopeData', 
      callback: (data) => setSensorData(prev => ({...prev, gyroscope: data})),
    },
    {
      eventName: 'magnetometerData',
      callback: (data) => setSensorData(prev => ({...prev, magnetometer: data})),
    },
  ]);
  
  return (
    <View>
      <Text>Sensor Data:</Text>
      <Text>{JSON.stringify(sensorData, null, 2)}</Text>
    </View>
  );
}
interface NativeEventEmitterStatic {
  new (nativeModule: any): NativeEventEmitter;
}

interface NativeEventEmitter {
  addListener(eventType: string, listener: Function): EmitterSubscription;
  removeAllListeners(eventType?: string): void;
  listenerCount(eventType: string): number;
}

interface EmitterSubscription {
  remove(): void;
}

// Device event emitters
interface DeviceEventEmitterStatic extends NativeEventEmitter {
  addListener(eventType: string, listener: Function): EmitterSubscription;
}

interface NativeAppEventEmitterStatic extends NativeEventEmitter {
  addListener(eventType: string, listener: Function): EmitterSubscription;
}

Low-Level Native Integration

UIManager

Access low-level UI manipulation methods for advanced native integration.

import {UIManager, findNodeHandle} from 'react-native';

// Measure component dimensions
function MeasureComponent() {
  const viewRef = useRef(null);
  const [dimensions, setDimensions] = useState(null);
  
  const measureView = () => {
    if (viewRef.current) {
      const handle = findNodeHandle(viewRef.current);
      
      UIManager.measure(handle, (x, y, width, height, pageX, pageY) => {
        setDimensions({x, y, width, height, pageX, pageY});
      });
    }
  };
  
  const measureInWindow = () => {
    if (viewRef.current) {
      const handle = findNodeHandle(viewRef.current);
      
      UIManager.measureInWindow(handle, (x, y, width, height) => {
        console.log('Position in window:', {x, y, width, height});
      });
    }
  };
  
  return (
    <View>
      <View
        ref={viewRef}
        style={{width: 200, height: 100, backgroundColor: 'blue'}}
      >
        <Text>Measure me</Text>
      </View>
      
      <Button title="Measure" onPress={measureView} />
      <Button title="Measure In Window" onPress={measureInWindow} />
      
      {dimensions && (
        <Text>
          Dimensions: {dimensions.width} x {dimensions.height}
          Position: ({dimensions.x}, {dimensions.y})
          Page Position: ({dimensions.pageX}, {dimensions.pageY})
        </Text>
      )}
    </View>
  );
}

// Focus management
function FocusManager() {
  const inputRef = useRef(null);
  
  const focusInput = () => {
    if (inputRef.current) {
      const handle = findNodeHandle(inputRef.current);
      UIManager.focus(handle);
    }
  };
  
  const blurInput = () => {
    if (inputRef.current) {
      const handle = findNodeHandle(inputRef.current);
      UIManager.blur(handle);
    }
  };
  
  return (
    <View>
      <TextInput
        ref={inputRef}
        placeholder="Manageable input"
        style={styles.input}
      />
      
      <Button title="Focus" onPress={focusInput} />
      <Button title="Blur" onPress={blurInput} />
    </View>
  );
}

// Layout animation configuration
function LayoutAnimationManager() {
  const configureLayoutAnimation = () => {
    if (UIManager.setLayoutAnimationEnabledExperimental) {
      UIManager.setLayoutAnimationEnabledExperimental(true);
    }
    
    const animationConfig = {
      duration: 300,
      create: {
        type: 'easeInEaseOut',
        property: 'opacity',
      },
      update: {
        type: 'easeInEaseOut',
      },
      delete: {
        type: 'easeInEaseOut',
        property: 'opacity',
      },
    };
    
    UIManager.configureNextLayoutAnimation(
      animationConfig,
      () => console.log('Animation completed'),
      (error) => console.error('Animation failed:', error)
    );
  };
  
  return (
    <Button title="Configure Layout Animation" onPress={configureLayoutAnimation} />
  );
}

// Custom view manager integration
function CustomNativeView() {
  const viewRef = useRef(null);
  
  const updateNativeProps = () => {
    if (viewRef.current) {
      const handle = findNodeHandle(viewRef.current);
      
      // Update native properties directly
      UIManager.updateView(handle, 'MyCustomView', {
        customProperty: 'newValue',
        color: '#ff0000',
      });
    }
  };
  
  const sendCommand = () => {
    if (viewRef.current) {
      const handle = findNodeHandle(viewRef.current);
      
      // Send command to native view
      UIManager.dispatchViewManagerCommand(
        handle,
        'customCommand',
        ['parameter1', 'parameter2']
      );
    }
  };
  
  return (
    <View>
      <View ref={viewRef} style={{width: 200, height: 200}}>
        <Text>Custom Native View</Text>
      </View>
      
      <Button title="Update Native Props" onPress={updateNativeProps} />
      <Button title="Send Command" onPress={sendCommand} />
    </View>
  );
}

// Performance monitoring
function PerformanceMonitor() {
  const [timing, setTiming] = useState({});
  
  const measureLayoutTime = () => {
    const startTime = performance.now();
    
    // Trigger layout calculation
    UIManager.manuallyApplyRTLCorrection && UIManager.manuallyApplyRTLCorrection(false);
    
    const endTime = performance.now();
    setTiming({layout: endTime - startTime});
  };
  
  return (
    <View>
      <Text>Layout Time: {timing.layout?.toFixed(2)}ms</Text>
      <Button title="Measure Layout" onPress={measureLayoutTime} />
    </View>
  );
}
interface UIManagerStatic {
  // Measurement
  measure(
    node: number,
    callback: (x: number, y: number, width: number, height: number, pageX: number, pageY: number) => void
  ): void;
  
  measureInWindow(
    node: number,
    callback: (x: number, y: number, width: number, height: number) => void
  ): void;
  
  measureLayout(
    node: number,
    relativeToNativeNode: number,
    onFail: () => void,
    onSuccess: (left: number, top: number, width: number, height: number) => void
  ): void;
  
  // Focus management
  focus(node: number): void;
  blur(node: number): void;
  
  // View updates
  updateView(node: number, viewName: string, props: any): void;
  
  // Commands
  dispatchViewManagerCommand(node: number, commandName: string, commandArgs?: any[]): void;
  
  // Layout animation
  configureNextLayoutAnimation(
    config: any,
    callback?: () => void,
    errorCallback?: (error: any) => void
  ): void;
  
  // Android specific
  setLayoutAnimationEnabledExperimental?(enabled: boolean): void;
  
  // Constants
  getConstants?(): {[key: string]: any};
  
  // View registry
  getViewManagerConfig?(viewManagerName: string): any;
}

interface findNodeHandleStatic {
  (componentOrHandle: any): number | null;
}

unstable_batchedUpdates

Batches multiple state updates into a single render cycle for performance optimization.

import {unstable_batchedUpdates} from 'react-native';

// Batch multiple state updates
function handleBulkUpdate(newItems) {
  unstable_batchedUpdates(() => {
    setItems(newItems);
    setLoading(false);
    setError(null);
    setLastUpdated(Date.now());
  });
}

// In event handlers that might trigger multiple updates
function handleComplexUpdate(data) {
  unstable_batchedUpdates(() => {
    // All these state updates will be batched together
    data.forEach(item => {
      updateItem(item.id, item.data);
      updateMetadata(item.metadata); 
      updateCache(item.cacheKey, item.value);
    });
  });
}

// Useful when working with native events that trigger multiple state changes
const handleNativeEvent = (event) => {
  unstable_batchedUpdates(() => {
    setPosition(event.position);
    setVelocity(event.velocity);
    setTimestamp(event.timestamp);
    setIsTracking(true);
  });
};
interface unstable_batchedUpdatesStatic {
  (callback: () => void): void;
}

Native Component Creation

requireNativeComponent

Create React components from native UI components.

import {requireNativeComponent, ViewPropTypes} from 'react-native';

// Create component from native view
const NativeMapView = requireNativeComponent('MapView');

// Wrapper component with prop validation
function MapView({region, markers, onRegionChange, ...props}) {
  return (
    <NativeMapView
      region={region}
      markers={markers}
      onRegionChange={onRegionChange}
      {...props}
    />
  );
}

MapView.propTypes = {
  region: PropTypes.shape({
    latitude: PropTypes.number.isRequired,
    longitude: PropTypes.number.isRequired,
    latitudeDelta: PropTypes.number.isRequired,
    longitudeDelta: PropTypes.number.isRequired,
  }),
  markers: PropTypes.arrayOf(PropTypes.shape({
    latitude: PropTypes.number.isRequired,
    longitude: PropTypes.number.isRequired,
    title: PropTypes.string,
  })),
  onRegionChange: PropTypes.func,
  ...ViewPropTypes,
};

// Custom video player component
const NativeVideoPlayer = requireNativeComponent('VideoPlayer');

function VideoPlayer({source, onProgress, onEnd, style, ...props}) {
  const handleProgress = (event) => {
    onProgress?.(event.nativeEvent);
  };
  
  const handleEnd = (event) => {
    onEnd?.(event.nativeEvent);
  };
  
  return (
    <NativeVideoPlayer
      source={source}
      onProgress={handleProgress}
      onEnd={handleEnd}
      style={[{width: '100%', height: 200}, style]}
      {...props}
    />
  );
}

// Chart component with native implementation
const NativeChartView = requireNativeComponent('ChartView');

function ChartView({data, chartType, style, onDataPointPress}) {
  const handleDataPointPress = (event) => {
    const {index, value} = event.nativeEvent;
    onDataPointPress?.({index, value});
  };
  
  return (
    <NativeChartView
      data={data}
      chartType={chartType}
      onDataPointPress={handleDataPointPress}
      style={[{height: 300}, style]}
    />
  );
}

// Camera view component
const NativeCameraView = requireNativeComponent('CameraView');

function CameraView({onPhotoCapture, onError, ...props}) {
  const cameraRef = useRef(null);
  
  const capturePhoto = () => {
    if (cameraRef.current) {
      const handle = findNodeHandle(cameraRef.current);
      UIManager.dispatchViewManagerCommand(handle, 'capturePhoto', []);
    }
  };
  
  const handlePhotoCapture = (event) => {
    const {uri, width, height} = event.nativeEvent;
    onPhotoCapture?.({uri, width, height});
  };
  
  const handleError = (event) => {
    onError?.(event.nativeEvent.error);
  };
  
  return (
    <View>
      <NativeCameraView
        ref={cameraRef}
        onPhotoCapture={handlePhotoCapture}
        onError={handleError}
        style={{width: '100%', height: 400}}
        {...props}
      />
      
      <Button title="Capture Photo" onPress={capturePhoto} />
    </View>
  );
}

// Higher-order component for native components
function withNativeComponent(nativeComponentName, defaultProps = {}) {
  const NativeComponent = requireNativeComponent(nativeComponentName);
  
  return function WrappedNativeComponent(props) {
    const combinedProps = {...defaultProps, ...props};
    
    return <NativeComponent {...combinedProps} />;
  };
}

// Usage with HOC
const CustomSlider = withNativeComponent('CustomSlider', {
  minimumValue: 0,
  maximumValue: 100,
  step: 1,
});
interface requireNativeComponentStatic {
  <T = any>(viewName: string): React.ComponentType<T>;
}

// Native component prop types
interface NativeComponentProps {
  style?: ViewStyle;
  
  // Event handlers (converted from native events)
  [key: `on${string}`]: ((event: NativeSyntheticEvent<any>) => void) | undefined;
  
  // Other props passed to native component
  [key: string]: any;
}

// Example native component interfaces
interface MapViewProps extends NativeComponentProps {
  region?: {
    latitude: number;
    longitude: number;
    latitudeDelta: number;
    longitudeDelta: number;
  };
  markers?: Array<{
    latitude: number;
    longitude: number;
    title?: string;
    description?: string;
  }>;
  onRegionChange?: (event: NativeSyntheticEvent<{region: any}>) => void;
  onMarkerPress?: (event: NativeSyntheticEvent<{marker: any}>) => void;
}

interface VideoPlayerProps extends NativeComponentProps {
  source: {uri: string} | number;
  resizeMode?: 'contain' | 'cover' | 'stretch';
  repeat?: boolean;
  paused?: boolean;
  volume?: number;
  rate?: number;
  onProgress?: (event: NativeSyntheticEvent<{currentTime: number; duration: number}>) => void;
  onEnd?: (event: NativeSyntheticEvent<{}>) => void;
  onError?: (event: NativeSyntheticEvent<{error: string}>) => void;
}

This comprehensive native bridge documentation provides developers with all the tools needed to integrate JavaScript code with native platform functionality, create custom native modules, handle events, and build native UI components in React Native applications.

Install with Tessl CLI

npx tessl i tessl/npm-react-native@1000.0.0

docs

animation.md

core-components.md

index.md

native-bridge.md

platform-apis.md

react-hooks.md

styling.md

user-interaction.md

tile.json