4

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

Lenny Gonzalez
  • 123
  • 1
  • 1
  • 8

2 Answers2

9

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;
Tooba Ali
  • 344
  • 2
  • 5
  • This is progress!! However, would you happen to know why sometimes it gets stuck on the "Text" and doesn't go back to the icon when you're no longer hovering over it? Ex: https://gph.is/g/EvpYNo5 – Lenny Gonzalez Nov 06 '20 at 14:47
  • It happens because of the stale closure problem. `{hover ? "SKILLS" : }` is being rendered with a stale value of hover. You can [read more about stale closures here](https://dmitripavlutin.com/react-hooks-stale-closures/). I hope it helps. – Tooba Ali Nov 06 '20 at 16:07
1

A somewhat simpler option, use MUI tooltip component

<Tooltip title="Delete">
  <IconButton>
    <DeleteIcon />
  </IconButton>
</Tooltip>

enter image description here

Roman
  • 8,826
  • 10
  • 63
  • 103