React函数组件改写故障:自定义霓虹光标无法移动求助
解决自定义霓虹光标无法移动的问题
问题根源分析
你的代码存在4个关键错误,导致光标无法正常跟随鼠标移动:
- 状态更新传值错误:
handleMouseMove中给setTop、setLeft传递了对象,但这两个状态的初始值是数字类型,会导致状态变成对象,无法正确应用到样式上。 - 样式绑定错误:渲染img时误将状态更新函数
setTop、setLeft绑定到style属性,而非状态变量本身,且未添加CSS单位px。 - useEffect缺少依赖数组:未设置依赖数组会导致组件每次状态更新时重复绑定/解绑事件,引发性能问题和异常。
- 初始状态未定义:
isCustomCursor初始值为undefined,虽然不影响首次切换,但显式设置初始值能避免潜在逻辑问题。
错误修复与代码说明
1. 修正状态更新逻辑
将对象传值改为直接传递数值:
// 错误写法 setTop({ top: event.pageY }); setLeft({ left: event.pageX }); // 正确写法 setTop(event.pageY); setLeft(event.pageX);
2. 修正样式绑定
使用状态变量并添加px单位:
// 错误写法 style={{ position: 'absolute', top: setTop, left: setLeft, pointerEvents: 'none', }} // 正确写法 style={{ position: 'absolute', top: `${top}px`, left: `${left}px`, pointerEvents: 'none', }}
3. 给useEffect添加空依赖数组
确保事件只在组件挂载时绑定一次:
// 错误写法 React.useEffect(() => { /* ... */ }); // 正确写法 React.useEffect(() => { /* ... */ }, []);
4. 显式设置初始状态
给isCustomCursor设置初始值false:
// 错误写法 const [isCustomCursor, setIsCustomCursor] = React.useState(); // 正确写法 const [isCustomCursor, setIsCustomCursor] = React.useState(false);
完整修复后的代码
function App() { const [isCustomCursor, setIsCustomCursor] = React.useState(false); function handleChange() { setIsCustomCursor(!isCustomCursor); } return ( <> <label> <input type="checkbox" onChange={handleChange}/> Включить неоновый курсор </label> {isCustomCursor && <NeonCursor/>} </> ); } function NeonCursor() { const [top, setTop] = React.useState(0); const [left, setLeft] = React.useState(0); React.useEffect(() => { function handleMouseMove(event) { setTop(event.pageY); setLeft(event.pageX); } document.addEventListener('mousemove', handleMouseMove); document.documentElement.classList.add('no-cursor'); return () => { document.documentElement.classList.remove('no-cursor'); document.removeEventListener('mousemove', handleMouseMove); }; }, []); return ( <img src="https://code.s3.yandex.net/web-code/react/cursor.svg" width={30} style={{ position: 'absolute', top: `${top}px`, left: `${left}px`, pointerEvents: 'none', }} /> ); } ReactDOM.render(<App/>, document.querySelector('#root'));
内容的提问来源于stack exchange,提问作者PowerHAHA
相关产品推荐
相关产品推荐

