In many mobile applications it is essential to be able to use the device camera. Maybe you’re creating the next Instagram or other photo sharing application.
Previously I wrote how to use the device camera in Ionic Framework, but how might we do the same with React Native?
Lucky for us, with React Native, there is an external component that lets us use the camera. Using react-native-camera by Loch Wansbrough, we have access to both the front and back device camera.
A few things to note about this particular tutorial before you get too invested. At the time of writing this, React Native works pretty much only for iOS. This means you’ll need to be using a Mac to develop with. As of right now the iOS simulators available in Xcode 6.4 do not support use of the camera. This means you’ll need to test on a native device.
With all this said, if you wish to continue, open your Terminal and execute the following command:
react-native init ReactProject
As mentioned earlier, we’re going to be using an external component. Download it to your project by first setting the project as your current working directory in your Terminal and running the following command:
npm install react-native-camera --save
The plugin has now been downloaded. At the time of writing this tutorial, I was using commit b1daed1 from the GitHub repository. The component may be downloaded, but you still need to include it in your Xcode project. This can be done with the following steps:
The component is now ready to be used. More information on adding components can be found in the official React Native documentation.
It should be noted that some of the code you’ll see here was taken directly from the react-native-camera component’s documentation.
Open your project’s index.ios.js file and add the following line:
var Camera = require("react-native-camera");
The above line will load the class so we can make calls to the component via JavaScript. When our application initializes we want to make sure the camera is shooting from the back. This can be done by adding the following to the getInitialState
function:
getInitialState: function() {
return {
cameraType: Camera.constants.Type.back
}
}
Inside the render
function we can add the Camera
tag. Any child tags that exist in this tag will be overlays to the camera. For example:
<Camera
ref="cam"
style={styles.container}
type={this.state.cameraType}>
<View style={styles.buttonBar}>
<TouchableHighlight style={styles.button} onPress={this._switchCamera}>
<Text style={styles.buttonText}>Flip</Text>
</TouchableHighlight>
<TouchableHighlight style={styles.button} onPress={this._takePicture}>
<Text style={styles.buttonText}>Take</Text>
</TouchableHighlight>
</View>
</Camera>
In the above snippet we use the camera with a two button overlay. The overlay buttons will allow for changing the camera between front and back as well as taking the photo. The two TouchableHighlight
tags call the _switchCamera
and _takePicture
functions. They can be see below:
_switchCamera: function() {
var state = this.state;
state.cameraType = state.cameraType === Camera.constants.Type.back ? Camera.constants.Type.front : Camera.constants.Type.back;
this.setState(state);
}
The above code just uses a ternary operator to switch the camera type and store it as a state.
_takePicture: function() {
this.refs.cam.capture(function(err, data) {
console.log(err, data);
});
}
When it comes to taking the picture we make use of the reference we set in the Camera
tag.
The full index.ios.js file I was using can be seen below:
"use strict";
var React = require("react-native");
var Camera = require("react-native-camera");
var {
AppRegistry,
StyleSheet,
Text,
View,
TextInput,
TouchableHighlight,
} = React;
var ReactProject = React.createClass({
getInitialState: function() {
return {
cameraType: Camera.constants.Type.back
}
},
render: function() {
return (
<Camera
ref="cam"
style={styles.container}
type={this.state.cameraType}>
<View style={styles.buttonBar}>
<TouchableHighlight style={styles.button} onPress={this._switchCamera}>
<Text style={styles.buttonText}>Flip</Text>
</TouchableHighlight>
<TouchableHighlight style={styles.button} onPress={this._takePicture}>
<Text style={styles.buttonText}>Take</Text>
</TouchableHighlight>
</View>
</Camera>
);
},
_switchCamera: function() {
var state = this.state;
state.cameraType = state.cameraType === Camera.constants.Type.back ? Camera.constants.Type.front : Camera.constants.Type.back;
this.setState(state);
},
_takePicture: function() {
this.refs.cam.capture(function(err, data) {
console.log(err, data);
});
}
});
var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "transparent",
},
buttonBar: {
flexDirection: "row",
position: "absolute",
bottom: 25,
right: 0,
left: 0,
justifyContent: "center"
},
button: {
padding: 10,
color: "#FFFFFF",
borderWidth: 1,
borderColor: "#FFFFFF",
margin: 5
},
buttonText: {
color: "#FFFFFF"
}
});
AppRegistry.registerComponent('ReactProject', () => ReactProject);
The application will look like this:
Of course I took the screenshot from the simulator which is why it is just black. If you wanted to get fancy you could switch out the text buttons for glyph icon buttons.
With the help of components, react-native-camera in particular, we can add device camera support to our React Native mobile application. This gives us the ability to take photos and switch between the front and rear cameras of the device.