You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

寻求适配USB条码扫描器的ReactJS库,实现扫码自动更新状态

解决ReactJS中USB条码扫描器的扫码检测问题

一、修复use-scan-detection的document is undefined错误

这个错误通常出现在服务端渲染(SSR)环境(如Next.js)中,因为服务端执行时不存在浏览器的document对象。可以通过以下两种方式解决:

1. 客户端动态加载hook

在组件挂载后(确保处于客户端环境)再加载并使用该hook:

import { useState, useEffect } from 'react';

const BarcodeScanner = () => {
  const [scannedCode, setScannedCode] = useState('');

  useEffect(() => {
    // 仅在客户端环境初始化扫描检测
    if (typeof document !== 'undefined') {
      import('use-scan-detection').then(({ useScanDetection }) => {
        useScanDetection({
          onComplete: (code) => {
            setScannedCode(code);
            console.log('扫描到条码:', code);
          },
          minLength: 6, // 过滤过短的无效输入
          scanButtonKeyCode: 13, // 多数扫描器默认用回车作为结束符
        });
      });
    }
  }, []);

  return <p>扫描结果: {scannedCode}</p>;
};

export default BarcodeScanner;

2. 禁用组件的服务端渲染

如果是Next.js项目,可通过next/dynamic动态导入组件并关闭SSR:

import dynamic from 'next/dynamic';

const BarcodeScanner = dynamic(() => import('./BarcodeScanner'), {
  ssr: false,
});

export default BarcodeScanner;

二、手动实现USB扫码监听(无需第三方库)

USB条码扫描器本质是模拟快速键盘输入,通常会以回车(Enter)作为输入结束符。可以通过监听全局键盘事件,结合输入间隔区分手动输入和扫码:

import { useState, useEffect } from 'react';

const USBBarcodeScanner = () => {
  const [scannedCode, setScannedCode] = useState('');
  const [inputBuffer, setInputBuffer] = useState('');
  const [lastKeyTime, setLastKeyTime] = useState(Date.now());

  useEffect(() => {
    const handleKeyDown = (e) => {
      // 仅处理普通字符和回车/制表符
      if (e.key.length === 1 || ['Enter', 'Tab'].includes(e.key)) {
        const currentTime = Date.now();
        // 扫码的按键间隔通常小于100ms,手动输入间隔更长
        const isContinuousScan = currentTime - lastKeyTime < 100;

        if (['Enter', 'Tab'].includes(e.key)) {
          // 结束符触发扫码完成
          if (inputBuffer.length > 0) {
            setScannedCode(inputBuffer);
            setInputBuffer('');
          }
        } else {
          // 连续快速输入时追加字符,否则重置缓冲区(区分手动输入)
          setInputBuffer(prev => isContinuousScan ? prev + e.key : e.key);
          setLastKeyTime(currentTime);
        }
      }
    };

    window.addEventListener('keydown', handleKeyDown);
    return () => window.removeEventListener('keydown', handleKeyDown);
  }, [lastKeyTime]);

  return (
    <div>
      <h3>USB条码扫描监听</h3>
      <p>扫描内容: <strong>{scannedCode}</strong></p>
    </div>
  );
};

export default USBBarcodeScanner;

该方案无需依赖第三方库,可根据扫描器的实际配置调整间隔阈值(如150ms)或结束符。

内容的提问来源于stack exchange,提问作者Mohtep

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 18:40:33