You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React组件中鼠标事件处理函数内无法设置样式的问题

问题解答

1. 只读属性的本质

你遇到的TypeError,是因为React在把buttonStyle对象作为style prop传递给DOM按钮后,会将这个对象冻结为只读状态,防止意外修改导致渲染不一致。你在事件回调里直接修改buttonStyle.backgroundColor,其实是在修改已经被React冻结的对象属性,所以触发了只读错误,这和你用let声明buttonStyle无关。

2. 为什么用let还是只读?

let只是允许你重新赋值buttonStyle变量,但对象本身的可修改性被React的内部处理逻辑覆盖了——React会冻结用于DOM渲染的style对象,不管你用let还是var声明这个对象,只要它被传入了DOM元素的style prop,后续修改它的属性都会触发只读错误。

3. 正确的解决方法

React的渲染依赖状态变化,你应该通过状态驱动样式变化,而不是直接修改普通对象。这里有两种靠谱的实现方式:

方式一:基于hover状态动态生成样式对象

这其实就是你注释掉的if-else逻辑的优化写法,每次组件渲染时,都会根据hover状态生成新的buttonStyle对象,完全避开修改只读对象的问题:

import React, { useState } from "react";
 
function App() {
  
  let [ hover, setState] = useState(false);
 
  // 每次渲染根据hover状态生成新的样式对象
  let buttonStyle = {
    backgroundColor: hover ? 'black' : ''
  }
 
  function hoverActive(){
    setState(true);    
  }
 
  function hoverInactive(){
    setState(false);    
  }
 
  return (
    <div className="container">
      <h1>Hello</h1>
      <input type="text" placeholder="What's your name?" />
      <button style={buttonStyle} onMouseEnter={hoverActive} onMouseLeave={hoverInactive}>Submit</button>
    </div>
  );
}
 
export default App;

方式二:用useState直接管理样式对象

如果需要更复杂的样式管理,也可以把样式对象本身放进状态里:

import React, { useState } from "react";
 
function App() {
  
  let [ buttonStyle, setButtonStyle] = useState({
    backgroundColor: ''
  });
 
  function hoverActive(){
    setButtonStyle({ backgroundColor: 'black' });    
  }
 
  function hoverInactive(){
    setButtonStyle({ backgroundColor: '' });    
  }
 
  return (
    <div className="container">
      <h1>Hello</h1>
      <input type="text" placeholder="What's your name?" />
      <button style={buttonStyle} onMouseEnter={hoverActive} onMouseLeave={hoverInactive}>Submit</button>
    </div>
  );
}
 
export default App;

补充说明

你之前用if-else判断hover状态修改样式能正常工作,是因为那段逻辑在组件渲染阶段执行,每次都会生成新的buttonStyle对象,还没被React冻结就完成了赋值,所以不会报错;而事件回调是在渲染完成后触发的,此时buttonStyle已经被React冻结,修改就会报错。

内容的提问来源于stack exchange,提问作者Aravi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 07:36:29