使用React开发Chrome扩展时popup获取background日志出现无限循环问题
无限循环问题原因
- 最初版本的popup.js将
chrome.runtime.sendMessage直接写在React函数组件的顶层,函数组件的顶层代码会在每次组件渲染时全量执行。 - sendMessage的回调中调用了
setlogList更新组件状态,状态更新会触发组件重新渲染,进而再次执行顶层的sendMessage逻辑,再次触发状态更新,形成无限循环,因此控制台会反复打印日志。
修复方案
1. 弹窗侧逻辑优化
你修改后的代码已经解决了无限循环问题:将sendMessage逻辑放到依赖为空数组的useEffect中,空依赖的useEffect只会在组件首次挂载完成后执行一次,不会重复触发状态更新。
另外需要修复日志渲染的问题:当前map回调中注释了return语法,且存在多余的调试代码,调整后代码如下:
const [logList, setlogList] = useState<ILog[]>([]) useEffect(() => { chrome.runtime.sendMessage({ type: "log" }, res => { console.log(res); setlogList(res.log) }) }, []) <Modal title="Basic Modal" visible={isModalVisible} onOk={handleOk} onCancel={handleCancel}> { logList.map((val, index) => { return ( <React.Fragment key={index}> <p>{val.date}</p> <p>{val.level}</p> <p>{val.msg}</p> </React.Fragment> ) }) } </Modal>
2. background侧逻辑优化
现有background代码存在两个隐藏问题,需要同步修复:
- 类型定义错误:
static loggerList: string= []的类型声明和赋值不匹配,修改为static loggerList: ILog[] = [] - 重复注册消息监听器:当前
onMessage监听器注册逻辑放在loggerLists方法中,每次调用该方法都会新增一个监听器,导致同一个消息触发多次回调。建议将监听器注册逻辑移到模块顶层,保证全局只注册一次。
内容的提问来源于stack exchange,提问作者1146752369
相关产品推荐
相关产品推荐

