React.js 애플리케이션에서 바코드를 스캔하는 방법
17633 단어 tutorialtypescriptzxingreact
Cover: "someone scanning a barcode of a package with their smartphone, caricature" – DALL-E mini
편집: 이제 이것을 react-zxing 으로 새 NPM 패키지에 게시했습니다.
배경
이것은 나의 첫 번째 기사가 될 것입니다. 구현하기가 특히 어려웠고 훌륭한 자습서를 찾을 수 없었고 내 reddit post가 약간의 관심을 끌었기 때문에 이 글을 작성하게 되었습니다.
우리는 무엇을 만들고 있습니까?
사이드 프로젝트에 바코드 스캐너를 사용하고 싶었습니다Snxbox . 내 기준은 다음과 같습니다.
대안
사용할 수 있는 React 호환 패키지를 찾기 시작했습니다. 내가 찾은 즉각적인 패키지는
react-qr-barcode-scanner
간단한 드롭인 반응 구성 요소를 제공했습니다.반응 qr-바코드 스캐너
react-qr-barcode-scanner
는 바코드를 디코딩하기 위해 zxing
에 의존합니다. EAN 코드를 읽음으로써 일관되지 않은 결과로 인해 발생하는 버그를 발견할 때까지 한동안 사용했습니다. issue on zxing을 찾았는데 수정된 것 같습니다. 그러나 react-qr-barcode-scanner
는 여전히 문제가 있는 zxing
의 이전 버전을 사용했습니다.쿼카2
이것은 확장하는 또 다른 패키지입니다
zxing
. React와 함께 사용하는 방법에 대한 예제를 찾았지만 솔직히 it seemed daunting .html5-qrcode
또 다른 패키지 확장
zxing
. 구현은 a bit easier to follow 이었지만 이것도 zxing
의 이전 버전을 사용하는 것 같아서 사용에 대해 약간 신중했습니다.바코드 감지 API 사용
바코드 스캔을 위한 실험적 API가 있지만 안타깝게도 아직 지원이 제한적인 것 같습니다.
리팩토링 시도
결국 종속성을 업데이트하기 위해
react-qr-barcode-scanner
를 분기했지만 구현이 quite straight-forward부터 시작되었음을 발견했습니다.또한
react-qr-barcode-scanner
는 react-webcam
을 사용하여 zxing
에서 디코딩할 스냅샷을 일정 간격으로 찍는 비디오 요소로 카메라를 스트리밍합니다. 실제로 비디오 스트림 자체를 디코딩하지는 않습니다.실제로
zxing
를 사용하여 비디오 스트림에서 직접 읽고 비디오 요소에서 스트림을 미리 볼 수 있으므로 react-webcam
종속성이 중복됩니다.손을 더럽히다
관찰 결과 대부분의 대안은 디코딩에
zxing
를 사용하므로 아마도 안전한 방법일 것입니다.따라서
@zxing/library
패키지를 설치합니다. 그런 다음 리더 인스턴스를 만듭니다.import { BrowserMultiFormatReader } from '@zxing/library';
const reader = new BrowserMultiFormatReader();
그런 다음 메서드
decodeFromConstraints
를 사용하여 스트림에서 코드를 지속적으로 감지하고 비디오 요소에 표시할 수 있습니다. 첫 번째 인수는 구성 개체, 두 번째 인수는 스트리밍할 동영상 요소, 세 번째 인수는 디코딩 결과를 처리하는 콜백 함수입니다.import { BrowserMultiFormatReader } from '@zxing/library';
let videoElement: HTMLVideoElement;
reader.decodeFromConstraints(
{
audio: false,
video: {
facingMode: 'environment',
},
},
videoElement,
(result, error) => {
if (result) console.log(result);
if (error) console.log(error);
}
);
반응 구현
useRef
후크를 사용하여 비디오 요소를 참조에 보관하고 useEffect
로 디코딩을 시작할 수 있습니다. 가장 기본적인 구현은 다음과 같습니다.const BarcodeScanner = () => {
const videoRef = useRef<HTMLVideoElement>(null);
const reader = useRef(new BrowserMultiFormatReader());
useEffect(() => {
if (!videoRef.current) return;
reader.current.decodeFromConstraints(
{
audio: false,
video: {
facingMode: 'environment',
},
},
videoRef.current,
(result, error) => {
if (result) console.log(result);
if (error) console.log(error);
}
);
return () => {
reader.current.reset();
}
}, [videoRef]);
return <video ref={videoRef} />;
};
성능상의 이유로
BrowserMultiFormatReader
후크를 사용하여 useRef
를 한 번만 인스턴스화하고 해당 인스턴스의 useEffect
메서드를 호출하여 reset()
를 정리하는 것이 중요합니다.사용자 지정 후크 사용
기본 구현을 살펴보면 다음과 같은 몇 가지 개선 영역이 있음을 알 수 있습니다.
BarcodeScanner
소비자애플리케이션에서 비디오 요소를 렌더링하는 방법에서 논리를 분리할 수 있도록 사용자 지정 후크로 추출하여 개선할 수 있습니다.
이것이 최종 구현입니다.
import { BrowserMultiFormatReader, DecodeHintType, Result } from '@zxing/library';
import { useEffect, useMemo, useRef } from 'react';
interface ZxingOptions {
hints?: Map<DecodeHintType, any>;
constraints?: MediaStreamConstraints;
timeBetweenDecodingAttempts?: number;
onResult?: (result: Result) => void;
onError?: (error: Error) => void;
}
const useZxing = ({
constraints = {
audio: false,
video: {
facingMode: 'environment',
},
},
hints,
timeBetweenDecodingAttempts = 300,
onResult = () => {},
onError = () => {},
}: ZxingOptions = {}) => {
const ref = useRef<HTMLVideoElement>(null);
const reader = useMemo<BrowserMultiFormatReader>(() => {
const instance = new BrowserMultiFormatReader(hints);
instance.timeBetweenDecodingAttempts = timeBetweenDecodingAttempts;
return instance;
}, [hints, timeBetweenDecodingAttempts]);
useEffect(() => {
if (!ref.current) return;
reader.decodeFromConstraints(constraints, ref.current, (result, error) => {
if (result) onResult(result);
if (error) onError(error);
});
return () => {
reader.reset();
};
}, [ref, reader]);
return { ref };
};
그런 다음 다음과 같은 구성 요소에서 사용할 수 있습니다.
export const BarcodeScanner: React.FC<BarcodeScannerProps> = ({
onResult = () => {},
onError = () => {},
}) => {
const { ref } = useZxing({ onResult, onError });
return <video ref={ref} />;
};
어떻게 생각하니?
댓글로 알려주세요!
Reference
이 문제에 관하여(React.js 애플리케이션에서 바코드를 스캔하는 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/zodiapps/how-to-scan-barcodes-in-your-reactjs-application-2668텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)