React Native ViewShot

4.0.3 · active · verified Sun Apr 19

react-native-view-shot is a utility library for React Native applications, enabling developers to capture any rendered view or the entire screen as an image. It provides functionalities to save the captured image to a file, retrieve it as a Base64 encoded string, or other raw formats. The library is actively maintained, with version 4.0.3 being the current stable release, demonstrating a consistent cadence of updates to support the latest versions of React Native, iOS, and Android platforms. Key differentiators include its robust handling of various view types, including SurfaceView on Android, and continuous improvements in performance and platform compatibility, making it a reliable solution for screenshot and view snapshot requirements within the React Native ecosystem. It also offers dedicated web support since v3.7.0.

Common errors

Warnings

Install

Imports

Quickstart

Demonstrates how to use the `ViewShot` component with a `useRef` hook to capture a specific React Native view. The example sets capture options for PNG format and logs the resulting image URI, also showing an optional preview. Saving to the camera roll is commented out as it requires additional setup and permissions.

import React, { useRef, useState } from 'react';
import { Button, View, Text, Alert, Image, StyleSheet } from 'react-native';
import ViewShot from 'react-native-view-shot';
import { CameraRoll } from '@react-native-camera-roll/camera-roll'; // Peer dependency for saving

// Note: @react-native-camera-roll/camera-roll requires separate installation and linking,
// as well as appropriate permissions (e.g., WRITE_EXTERNAL_STORAGE on Android, NSPhotoLibraryUsageDescription on iOS).

const MyViewCapture = () => {
  const viewShotRef = useRef<ViewShot>(null);
  const [capturedUri, setCapturedUri] = useState<string | null>(null);

  const captureView = async () => {
    if (viewShotRef.current) {
      try {
        // Capture the view with specified options
        const uri = await viewShotRef.current.capture();
        setCapturedUri(uri);
        console.log('Image captured to:', uri);
        Alert.alert('Capture Success', `Image URI: ${uri}`);
        
        // Optional: Save to camera roll (requires @react-native-camera-roll/camera-roll and permissions)
        // try {
        //   const result = await CameraRoll.save(uri, { type: 'photo' });
        //   Alert.alert('Saved', `Image saved to camera roll: ${result}`);
        // } catch (saveError) {
        //   console.error('Failed to save to camera roll:', saveError);
        //   Alert.alert('Save Error', `Failed to save image: ${saveError}`);
        // }

      } catch (error) {
        console.error('Failed to capture view:', error);
        Alert.alert('Capture Error', `Failed to capture view: ${error}`);
      }
    } else {
      Alert.alert('Error', 'ViewShot ref is not available.');
    }
  };

  return (
    <View style={styles.container}>
      <ViewShot ref={viewShotRef} options={{ format: 'png', quality: 0.9, result: 'data-uri' }} style={styles.captureTarget}>
        <Text style={styles.title}>Hello ViewShot!</Text>
        <Text style={styles.subtitle}>This is a component that will be captured as an image.</Text>
        <Image 
          source={{ uri: 'https://via.placeholder.com/100/ADD8E6/000000?text=RN' }} 
          style={styles.image}
        />
      </ViewShot>

      {capturedUri && (
        <View style={styles.previewContainer}>
          <Text style={styles.previewText}>Captured Image Preview:</Text>
          <Image source={{ uri: capturedUri }} style={styles.previewImage} resizeMode="contain" />
        </View>
      )}

      <Button title="Capture View" onPress={captureView} />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#f0f0f0',
    padding: 20,
  },
  captureTarget: {
    backgroundColor: 'white',
    padding: 20,
    borderRadius: 10,
    alignItems: 'center',
    marginBottom: 30,
  },
  title: {
    fontSize: 24,
    fontWeight: 'bold',
    marginBottom: 10,
  },
  subtitle: {
    fontSize: 16,
    textAlign: 'center',
    marginBottom: 15,
  },
  image: {
    width: 100,
    height: 100,
    borderRadius: 5,
  },
  previewContainer: {
    marginTop: 20,
    alignItems: 'center',
    marginBottom: 20,
  },
  previewText: {
    fontSize: 18,
    fontWeight: 'bold',
    marginBottom: 10,
  },
  previewImage: {
    width: 250,
    height: 250,
    borderWidth: 1,
    borderColor: '#ccc',
    backgroundColor: '#e8e8e8',
  },
});

export default MyViewCapture;

view raw JSON →