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

Next.js中更新State数组导致html5-qrcode组件消失求助

问题解决:Next.js集成html5-qrcode后更新State导致组件消失

核心原因

每次调用setDecodedResults更新状态时,组件会触发重新渲染,此时onNewScanResult函数会被重新创建新的实例。html5-qrcode组件检测到onScanSuccess回调引用变化后,会重新初始化扫码器,这个过程中相机流可能中断,导致组件看起来"消失"。

解决方案

  1. 用useCallback稳定回调引用
    借助React的useCallback钩子,确保onNewScanResult的引用在组件渲染周期内保持稳定,避免触发扫码组件不必要的重新初始化。

  2. 添加重复结果过滤(可选)
    避免重复添加相同的扫描结果,减少不必要的状态更新和组件渲染。

修改后的核心代码

import { useState, useCallback } from 'react';
import Html5QrcodeScanner from 'html5-qrcode';

// App Router下需添加客户端组件标识
'use client';

const QrScanner = () => {
  const [decodedResults, setDecodedResults] = useState([]);

  // 用useCallback包裹回调,空依赖数组保证引用稳定
  const onNewScanResult = useCallback((decodedText, decodedResult) => {
    console.log("App [result]", decodedResult);
    setDecodedResults(prev => {
      // 过滤重复结果,避免重复更新
      const isDuplicate = prev.some(item => item.text === decodedResult.text);
      if (isDuplicate) return prev;
      return [...prev, decodedResult];
    });
  }, []);

  return (
    <div>
      <div id="qr-reader"></div>
      {/* 展示扫描结果 */}
      <ul>
        {decodedResults.map((result, index) => (
          <li key={index}>{result.text}</li>
        ))}
      </ul>
    </div>
  );
};

export default QrScanner;

额外注意事项

  • 若使用Next.js App Router,必须确保扫码组件是客户端组件,在文件顶部添加'use client'指令。
  • 保证扫码容器元素(如id="qr-reader")的DOM结构稳定,不要在每次渲染时动态创建或销毁该元素。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 05:58:26