There is an icon which says call is active, with classname "callConnect". When I hover on the icon, the icon should change, the new icon would be of classname "callDisconnect"
I am just writing a snippet to show my implementation which is not working:
I am using useRef and a functionto update
const hover = useRef(false)
const updateHoverState = (val: boolean) => {
hover.current = val
}
In my component i have a method which renders the icon as so:
<div onm ouseOver={() => {
updateHoverState(true)
console.log("hovering", hover.current)}
}
onm ouseOut={() => {
updateHoverState(false)
console.log("coming out", hover.current)}
}
>
{console.log("rendering", hover.current)} //not working
{hover.current ? <Icon onClick={() => { }} className={"callDisconnect"} /> :
<Icon onClick={() => { }} className={"callConnect"} />}
</div>
When i run the code, the I see that hover is getting updated to true and false properly when I hover and move out, but the icons are not changing. Re-rendering is not happening. How to fix please help.
Please note: I have already tried using useState, since it did not work, I switched to useRef.
useState:
const [hover, setHover] = useState(false)
<div onm ouseOver={() => {
setHover(true)
}
onm ouseOut={() => {
setHover(false)
}
>
{hover ? <Icon onClick={() => { }} className={"callDisconnect"} /> :
<Icon onClick={() => { }} className={"callConnect"} />} //not updating on hover
</div>
CodePudding user response:
The only way to cause a rerender in react is to set state. So instead of using a ref, use a state variable:
const App = () => {
const [hover, setHover] = React.useState(false);
return (
<div
style={{ width: 50, height: 50 }}
onm ouseOver={() => {
setHover(true);
}}
onm ouseOut={() => {
setHover(false);
}}
>
{hover ? (
<div style={{ width: 50, height: 50 }} onClick={() => {}} className={"callDisconnect"} />
) : (
<div style={{ width: 50, height: 50 }} onClick={() => {}} className={"callConnect"} />
)}
</div>
);
};
ReactDOM.render(<App />, document.getElementById("app"));
.callConnect {
background-color: green
}
.callDisconnect {
background-color: red
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>
<div id="app"></div>
CodePudding user response:
You need to use the useState
hook instead of useRef
to make your component re-render. Also you can apply the condition directly in the className
instead of repeating the whole component just for a class change:
const [hover, setHover] = useState(false);
<div
onm ouseOver={() => setHover(true)}
onm ouseOut={() => setHover(false)}
>
<Icon onClick={() => {}} className={hover ? "callDisconnect" : "callConnect"} />
</div>;