[英]Why I am not able to set the style inside the function of mouse event handler inside React component?
My code below: I am learning ReactJS.我的代码如下:我正在学习 ReactJS。 Trying to change the background colour of the button on mouse hover.尝试更改鼠标 hover 上按钮的背景颜色。 I know css:hover is the easiest approach.我知道 css:hover 是最简单的方法。 But doing this implementation to learn.但是做这个实现要学。
It works fine if I check the 'hover' value using if else condition.如果我使用 if else 条件检查“悬停”值,它工作正常。 But it gives the error "TypeError但它给出了错误“TypeError
Cannot assign to read only property 'backgroundColor' of object '#'" when I try to set the background colour inside the onMouseEnter and onMouseLeave event handler functions.当我尝试在 onMouseEnter 和 onMouseLeave 事件处理函数中设置背景颜色时,无法分配给 object '#'" 的只读属性 'backgroundColor'。
What is the read-only property here?这里的只读属性是什么? I have not made it const.我还没有把它变成常量。 Is it read-only by default?默认是只读的吗? How do I override it?我如何覆盖它?
import React, { useState } from "react";
function App() {
let [ hover, setState] = useState(false);
let buttonStyle = {
backgroundColor:''
}
function hoverActive(){
setState(true);
buttonStyle.backgroundColor='black';
}
function hoverInactive(){
setState(false);
buttonStyle.backgroundColor='';
}
if(hover){
//buttonStyle.backgroundColor='black';
}
else{
//buttonStyle.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;
It has to do with how object works in javascript.它与 object 在 javascript 中的工作方式有关。 Refer.. Cannot assign to read only property 'name' of object '[object Object]'参考.. 无法分配给 object '[object Object]' 的只读属性 'name'
You can take Reference of the object and use State or Ref to update the Background color.您可以参考 object 并使用 State 或 Ref 来更新背景颜色。
import React, { useState } from "react";
function App() {
let [hover, setState] = useState(false);
let buttonStyle = {
backgroundColor: "",
};
const [ButtonStyle, setButtonStyle] = useState(buttonStyle);
function hoverActive() {
setState(true);
const data = { ...buttonStyle, backgroundColor: "green" };
setButtonStyle(data);
}
function hoverInactive() {
setState(false);
const data = { ...buttonStyle, backgroundColor: "" };
setButtonStyle(data);
}
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;
Few ways to achieve what you want:实现您想要的几种方法:
The issue you have now in your code is buttonStyle
not being a state and React just ignores the changes you make to that variable.您现在在代码中遇到的问题是buttonStyle
不是 state 并且 React 只是忽略了您对该变量所做的更改。
function App() { let [hover, setState] = React.useState(false); 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={{ backgroundColor: hover? "black": "", color: hover? "white": "black" }} onMouseEnter={hoverActive} onMouseLeave={hoverInactive} > Submit </button> </div> ); } ReactDOM.render(<App />, document.querySelector('.react'));
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script> <div class='react'></div>
You can achieve it using a React ref (using useRef
hook for your function component):您可以使用 React ref 来实现它(对 function 组件使用useRef
挂钩):
function App() { const buttonRef = React.useRef(null); function hoverActive() { buttonRef.current.style.backgroundColor = "black"; buttonRef.current.style.color = "white"; } function hoverInactive() { buttonRef.current.style.color = "black"; buttonRef.current.style.backgroundColor = ""; } return ( <div className="container"> <h1>Hello</h1> <input type="text" placeholder="What's your name?" /> <button ref={buttonRef} onMouseEnter={hoverActive} onMouseLeave={hoverInactive} > Submit </button> </div> ); } ReactDOM.render(<App />, document.querySelector('.react'));
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script> <div class='react'></div>
function App() { return ( <div className="container"> <h1>Hello</h1> <input type="text" placeholder="What's your name?" /> <button id="my-button">Submit</button> </div> ); } ReactDOM.render(<App />, document.querySelector('.react'));
#my-button:hover { background-color: black; color: white; }
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script> <div class='react'></div>
buttonStyle does not cause the component to be re-rendered as a result the value cannot be updated or manipulated. buttonStyle 不会导致组件重新渲染,因为值无法更新或操作。 A good approach would be the useState hook and update the state as needed一个好的方法是 useState 挂钩并根据需要更新 state
const [buttonStyle, setButtonStyle] = useState({ backgroundColor: '' })
const handleHover = () => {
setState(!hover);
if (hover) {
setButtonStyle({ ...buttonStyle, backgroundColor: '#fff' });
} else {
setButtonStyle({ ...buttonStyle, backgroundColor: 'red' });
}
};
<div className="container">
<h1>Hello</h1>
<input type="text" placeholder="What's your name?" />
<button
style={buttonStyle}
onMouseEnter={handleHover}
onMouseLeave={handleHover}
>
Submit
</button>
</div>
I'm using the spread operator as its standard practice when setting object state.在设置 object state 时,我使用扩展运算符作为其标准做法。 This does not mutate the original state.这不会改变原始 state。 Best practice to name your setState based on what they do, eg setButtonStyle, setHoveredOn根据他们所做的事情来命名你的 setState 的最佳实践,例如 setButtonStyle、setHoveredOn
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.