React开发鼠标轨迹记录页时mousemove事件仅在点击后触发问题
问题根因
你当前代码中的records数组实际上已经在鼠标移动时正常更新,只是你仅在点击按钮的逻辑中打印该数组、同时控制列表渲染的displayMessage默认值为false,才会产生只有点击按钮时数组才更新的错觉。不过代码存在几个实际bug需要修复:
- 事件监听移除失效:
addEventListener和removeEventListener传入的是两个独立的匿名箭头函数,引用不一致,组件卸载时无法正确移除mousemove监听,会造成内存泄漏。 - 性能损耗严重:每次鼠标移动都调用
setState触发组件重渲染,当记录数较多、且开启展示时,全量重渲染列表会导致页面卡顿。 - 列表key值不规范:使用
indexOf(record)作为key值,每次数组更新都会重新计算所有项的索引,进一步降低渲染性能。
修复方案
- 把mousemove监听函数存为实例属性,保证添加和移除的是同一个引用
- 用ref存储轨迹数据,避免频繁触发重渲染,仅在点击按钮需要展示时才把数据同步到state
- 给每条轨迹生成唯一key值
修复后完整代码
import React, {Component, createRef} from 'react'; class MouseRecord extends Component { constructor(props) { super(props); this.state = { displayMessage: false, showRecords: [] } // 用ref存储轨迹数据,不触发频繁重渲染 this.recordsRef = { current: [] } // 把监听函数存为实例属性,保证添加和移除是同一个引用 this.mouseMoveHandler = this.handleMouseMove.bind(this) this.handleClick = this.handleClick.bind(this); } handleClick() { // 点击按钮时才把ref的数据同步到state,触发渲染 this.setState(prevState => ({ displayMessage: !prevState.displayMessage, showRecords: this.recordsRef.current })); } handleMouseMove(e) { e.preventDefault(); if (this.recordsRef.current.length <= 100000){ this.recordsRef.current.push({ cor_X: e.clientX, cor_Y: e.clientY, width: window.innerWidth, height: window.innerHeight, timestamp: new Date().toUTCString() }) } } componentDidMount() { document.addEventListener('mousemove', this.mouseMoveHandler); } componentWillUnmount() { document.removeEventListener('mousemove', this.mouseMoveHandler); } render(){ return( <div className="box"> <button onClick={this.handleClick}>点击获取鼠标轨迹记录</button> <div> {this.state.displayMessage && this.state.showRecords.length > 0 ? this.state.showRecords.map((record, index) => { return ( <div key={`${record.timestamp}-${record.cor_X}-${record.cor_Y}-${index}`}> <p>X坐标: {record.cor_X}</p> <p>Y坐标: {record.cor_Y}</p> <p>窗口宽度: {record.width}</p> <p>窗口高度: {record.height}</p> <p>时间戳: {record.timestamp}</p> <br/> <br/> </div> ); }) : null} </div> </div> ); } } export default MouseRecord;
内容的提问来源于stack exchange,提问作者Benedict Howard
相关产品推荐
相关产品推荐

