so I am attempting to display text when you hover over a mouse. I am using React-Icons library and for styling using Styled-Components
I have 4 icons on my navbar - Home - About - Skills - Work
Each button is its own component in order for the hover to work properly so when i hover over 1 icon it doesnt display the text for all of them
import React, { useState } from 'react';
import { SkillsButton } from './SkillsBtnElements'
const SkillsBtn = () => {
const [hover, setHover] = useState(false);
const onHover = () => {
setHover(!hover)
}
return (
<div onMouseEnter={onHover} onMouseLeave={onHover} role="button" tabIndex='-3' >
{ hover ? "SKILLS" : <SkillsButton /> }
</div>
)
}
export default SkillsBtn;
And for styling i have
import styled from 'styled-components';
import { GiGearHammer } from 'react-icons/gi';
export const SkillsButton = styled(GiGearHammer)`
font-size: 1.75rem;
color: white;
flex-grow: 1;
cursor: pointer;
@media screen and (max-width: 960px) {
transition: all 0.2s ease-in-out;
font-size: 1rem;
color: white;
}
&:hover {
transition: all 0.2s ease-in-out;
}
`;
I do achieve a hover effect, but when I constantly hover the icon the logic seems to get messed up bc then its only the text that appears and when i hover over the text the icon appears...which isn't the desired effect
Example: https://gph.is/g/4ARQoRV
The abnormal effect is due to the stale closure problem. {hover ? "SKILLS" : <SkillsButton />}
is being rendered with a stale value of hover.
If you want the text to only appear when the mouse is over the div, try creating two separate functions for onMouseEnter and onMouseLeave events. Like this:
import React, { useState } from "react";
import { SkillsButton } from './SkillsBtnElements'
const SkillsBtn = () => {
const [hover, setHover] = useState(false);
const onHover = () => {
setHover(true);
};
const onLeave = () => {
setHover(false);
};
return (
<div
onMouseEnter={onHover}
onMouseLeave={onLeave}
role="button"
tabIndex="-3"
>
{hover ? "SKILLS" : <SkillsButton />}
</div>
);
};
export default SkillsBtn;