My code below: I am learning ReactJS. Trying to change the background colour of the button on mouse hover. I know css:hover is the easiest approach. But doing this implementation to learn.
It works fine if I check the 'hover' value using if else condition. But it gives the error "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.
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;
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.
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):
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>