React/JS点击追踪程序卡顿:7次点击后失效求助
问题:React点击追踪程序仅支持7次点击后卡顿
我是React、JS新手,编写了一个仅十行的小程序,用于追踪网页中的点击操作并在文本元素中显示点击坐标。程序看似简单且能正常运行,但仅支持7次点击,之后程序就会卡顿,无法执行后续操作、显示新的点击坐标,页面也停止更新。无论在本地Chrome、Safari浏览器还是在线沙箱中运行,都会出现此问题。
代码如下:
import "./styles.css"; import React from "react"; import { useState } from "react"; export default function App() { const [coordinates, setCoordinates] = useState({ x: 1, y: 1 }); function handleClick(e) { setCoordinates({ x: e.screenX, y: e.screenY }); } document.addEventListener("click", handleClick); return ( <p> x: {coordinates.x}, y: {coordinates.y}; </p> ); }
问题原因
核心问题是每次组件渲染时都会重复给document绑定点击事件:
- 初始渲染时,绑定第一个
handleClick事件; - 点击后调用
setCoordinates,触发组件重新渲染,此时又会执行document.addEventListener("click", handleClick),绑定新的handleClick函数; - 每点击一次就多绑定一个事件处理函数,后续点击时会同时触发所有绑定的
handleClick,多次调用setCoordinates,导致组件频繁渲染,最终因事件监听堆积过多,浏览器性能耗尽,出现卡顿甚至无响应。
浏览器的渲染队列和事件处理队列被大量重复的更新请求占满,所以到第7次左右就会出现明显卡顿(这个次数取决于浏览器性能,但本质是事件监听不断累加)。
解决方法
用React的**副作用钩子useEffect**控制事件监听的绑定与解绑,确保只在组件挂载时绑定一次,卸载时解绑:
修改后的代码:
import "./styles.css"; import React from "react"; import { useState, useEffect } from "react"; export default function App() { const [coordinates, setCoordinates] = useState({ x: 1, y: 1 }); function handleClick(e) { setCoordinates({ x: e.screenX, y: e.screenY }); } useEffect(() => { // 组件挂载时绑定事件 document.addEventListener("click", handleClick); // 返回清理函数,组件卸载时解绑事件 return () => { document.removeEventListener("click", handleClick); }; }, []); // 空依赖数组,确保只执行一次 return ( <p> x: {coordinates.x}, y: {coordinates.y}; </p> ); }
排查这类问题的思路
- 检查事件监听的绑定时机:避免在组件渲染函数(函数组件的顶层代码)中直接绑定事件,因为每次渲染都会执行这段代码,导致重复绑定;
- 利用浏览器性能面板:打开Chrome DevTools的Performance标签,录制点击过程,查看是否有大量重复的组件渲染或事件触发;
- 打印调试信息:在
handleClick中添加console.log('click'),会发现每次点击后打印的次数越来越多,直接证明事件监听在堆积; - 牢记React渲染机制:函数组件的顶层代码会在每次状态更新后重新执行,所以任何有副作用的操作(比如绑定事件、修改DOM)都应该放在
useEffect中,并通过依赖数组控制执行时机。
内容的提问来源于stack exchange,提问作者Petro
相关产品推荐
相关产品推荐

