React QR Reader
react-qr-reader is a React component designed for scanning QR codes directly from a user's webcam within a web browser application. Currently in `3.0.0-beta-1`, it is actively developed and compatible with React versions 16.8.0 and higher due to its internal use of React Hooks. The library leverages `jsQR` for QR code detection and `webrtc-adapter` for camera access, ensuring broad browser compatibility across Chrome, Firefox, and Safari on various operating systems including macOS, Android, and iOS. Key features include support for different camera facing modes, customizable scan delays, and a prop-driven API for integration into React applications. It primarily serves use cases requiring real-time QR code scanning in web environments.
Common errors
-
Error: Invalid hook call. Hooks can only be called inside of the body of a function component.
cause Using `react-qr-reader` with an older version of React that does not support Hooks, or violating rules of hooks.fixEnsure your `react` and `react-dom` dependencies are `^16.8.0` or higher. Also, make sure the component is rendered within a proper React functional component context. -
NotAllowedError: Permission denied
cause The user denied camera access, or the page is not being served over HTTPS in a production environment.fixInstruct users to grant camera permissions. For production, ensure your application is deployed over HTTPS. For local development, `localhost` is typically allowed. -
TypeError: Cannot read properties of undefined (reading 'text')
cause Attempting to access `result.text` when `result` is null or undefined, which can happen if `onResult` is called with an error or no valid QR code detected.fixAdd a null-check for `result` before accessing its properties within the `onResult` callback: `if (!!result) { setData(result.text); }` -
MediaStreamError: ConstraintsNotSatisfiedError
cause The requested `constraints` (e.g., `facingMode: 'environment'`) cannot be met by the available camera devices.fixReview the `constraints` prop. The requested camera (front/rear) might not be available or the device doesn't support the specified resolution/aspect ratio. Consider more generic `constraints` or provide user options to select cameras.
Warnings
- breaking Version 2.0.0 changed how camera devices are selected, moving from `deviceId` to `facingMode`. This was a significant change for iOS 11 Safari support and better camera control.
- breaking The component requires `React >= 16.8.0` due to its internal reliance on React Hooks. Older React versions will not work.
- gotcha Camera access requires HTTPS in production environments for `getUserMedia` to function correctly. Without HTTPS, the browser will block camera access, leading to `NotAllowedError` or similar errors.
- gotcha On iOS 11 Safari and other platforms without full `getUserMedia` support, the library might throw an error or behave unexpectedly. Version 2.0.1 specifically added error throwing for platforms without GUM support.
- deprecated Older versions of the `jsQR` library used might be slower or less efficient. Version 1.1.2 upgraded to a faster fork of `jsQR`.
Install
-
npm install react-qr-reader -
yarn add react-qr-reader -
pnpm add react-qr-reader
Imports
- QrReader
const QrReader = require('react-qr-reader');import { QrReader } from 'react-qr-reader'; - QrReader (default import)
import { QrReader } from 'react-qr-reader';import QrReader from 'react-qr-reader';
- React & useState
import { useState } from 'react'; import React from 'react';import React, { useState } from 'react';
Quickstart
import React, { useState } from 'react';
import { QrReader } from 'react-qr-reader';
const MyQrScanner = () => {
const [scanResult, setScanResult] = useState('No result');
return (
<div style={{ width: '50%', margin: '0 auto' }}>
<h2>QR Code Scanner</h2>
<QrReader
onResult={(result, error) => {
if (!!result) {
setScanResult(result?.text);
}
if (!!error) {
// console.info(error); // Uncomment for debugging errors
}
}}
constraints={{ facingMode: 'environment' }} // Prefer rear camera
scanDelay={300} // Reduce delay for faster scans
videoContainerStyle={{ padding: '20px', border: '1px solid #ddd' }}
videoStyle={{ maxHeight: '300px' }}
/>
<p style={{ marginTop: '20px', fontWeight: 'bold' }}>Scanned Data: {scanResult}</p>
{scanResult === 'No result' && <p>Point your camera at a QR code.</p>}
</div>
);
};
export default MyQrScanner;