Next.js中更新State数组导致html5-qrcode组件消失求助
问题解决:Next.js集成html5-qrcode后更新State导致组件消失
核心原因
每次调用setDecodedResults更新状态时,组件会触发重新渲染,此时onNewScanResult函数会被重新创建新的实例。html5-qrcode组件检测到onScanSuccess回调引用变化后,会重新初始化扫码器,这个过程中相机流可能中断,导致组件看起来"消失"。
解决方案
用
useCallback稳定回调引用
借助React的useCallback钩子,确保onNewScanResult的引用在组件渲染周期内保持稳定,避免触发扫码组件不必要的重新初始化。添加重复结果过滤(可选)
避免重复添加相同的扫描结果,减少不必要的状态更新和组件渲染。
修改后的核心代码
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
相关产品推荐
相关产品推荐

