방명록
- [React.js] qr-scanner를 리액트에 적용하기!2023년 10월 05일 17시 29분 30초에 업로드 된 글입니다.작성자: DandyNow728x90반응형
1. react-qr-reader에서 qr-scanner로 갈아탄 이유!
react-qr-reader 라이브러리를 이용해서 이미 프로젝트를 진행했었는데 Adobe Express에서 생성한 QR을 읽지 못하는 것이 아닌가?! 이 외에도 사용감이 좋지 못했기에 다른 라이브러리를 찾아보았다. 그렇게 해서 발견한 라이브러리가 qr-scanner이다. react-qr-reader 처럼 리액트를 위해 만들어진 라이브러리는 아니었지만 공식 문서와 데모를 살펴본 후 더 고민할 필요가 없었다.
2. qr-scanner를 리액트에 적용하기!
2.1. qr-scanner를 설치
npm install --save qr-scanner
2.2. qr-scanner 리액트 컴포넌트에 적용
장치의 카메라를 통해 QR을 스캔하고 스캔된 QR의 URL 정보를 이용해 해당 사이트로 이동하도록 구현한 컴포넌트이다.
<video /> 태그에 카메라 영상이 표시된다. useRef 훅을 이용해 qr-scanner가 <video /> 돔을 핸들링하도록 하였다. qr-scanner는 useEffect 훅을 이용해 작성하였다.
import React, { useEffect, useState, useRef } from 'react'; import QrScanner from 'qr-scanner'; // qr-scanner 라이브러리 임폴트 export default React.memo(function Qrcode(props) { // qrError은 QR을 스캔할 카메라가 없거나 카메라 사용이 허가되지 않은 경우(에러)에 대한 useState훅이다. // qrError의 기본값은 false이고 QR 스캔이 불가능한 상태는 true이다. const [qrError, setQrError] = useState(false); // 스캔한 QR의 URL이 http 또는 https로 시작하는지 확인(리턴값 boolean) const isUrl = text => { const urlRegex = /(https?:\/\/[^\s]+)/g; return urlRegex.test(text); }; // QR 코드 스캔 결과 처리 const handleScan = data => { if (data) { if (isUrl(data.data)) { window.open(data.data); } else { // http 키워드가 없는 QR의 경우 http://를 붙여줌 window.open(`http://${data.data}`); } } }; const QrOptions = { // 핸드폰의 경우 외부 카메라, 셀프 카메라 여부 preferredCamera: 'environment', // 1초에 5번 QR 코드 감지한다. maxScansPerSecond: 5, // 노란색 사각 영역을 표시하고 그 안에서 QR스캔이 가능하다. highlightScanRegion: true, }; // <video> 돔에 qr-scanner를 적용하기 위한 useRef 훅 const videoRef = useRef(null); // QrScanner 라이브러리 사용 useEffect(() => { // QrScanner.hasCamera()로 장치에 카메라가 있는지 확인 QrScanner.hasCamera().then(hasCamera => { if (!hasCamera) { setQrError(true); } if (hasCamera) { const videoElem = videoRef.current; if (videoElem) { const qrScanner = new QrScanner( videoElem, result => { console.log('result : ', result); handleScan(result); }, QrOptions, ); // 카메라 사용이 허가되었는지 확인 qrScanner.start().catch(e => setQrError(true)); return () => qrScanner.destroy(); } } }); }, []); return ( <main id="qrcode"> {/* QR 스캔 카메라 작동할 경우 */} {!qrError && ( <video style={{ width: '100%', height: '100%', objectFit: 'contain', }} ref={videoRef} /> )} {/* QR 스캔 카메라 작동 안될 경우 */} {qrError && ( <div className="no-qr"> <p>실행할 수 없음</p> <small> 카메라가 작동하지 않는다면 휴대기기의 <br /> 카메라(QR리더기)를 직접 작동시켜 주세요. </small> </div> )} </main> ); });
728x90반응형'언어·프레임워크 > React.js' 카테고리의 다른 글
[React.js] 웹 카메라 제어 : http에서 카메라 접근 안돼 ㅠ_ㅠ (0) 2023.10.12 [React.js] 웹 카메라 제어 : 사진 촬영 기능 위해 react-camera-pro 설치, Styled-Components도 필요! (0) 2023.10.12 [React.js] 리덕스 툴킷 createSlice 놀랍구나! (0) 2023.09.27 [React.js] useState 상태값 초기화로 좋지 못한 사용자 경험 개선 (0) 2023.09.22 [React.js] 모바일에서도 작동하는 텍스트 클립보드 복사 (0) 2023.09.15 다음글이 없습니다.이전글이 없습니다.댓글