Search code examples
htmlreactjsmouseoverdestructuring

How can I change HTML content on hover in React?


Here is the header section of my website-to-be.

Eds header section

Primary goal:

To hover over an icon and change the Logo text in the top right to reflect the icon which is being hovered over. For example, hovering over the second icon </> will change 'edwindharris' to 'projects'. The default needs to be 'edwindharris'.

Secondary goal:

For the transition between the changing headings to be a quick (.2s ish) fade.

Here is the incomplete code I have so far, which I would greatly appreciate help in completing:

const HeaderDesktop = () => {

    const homeHeading = {
        default:'edwin' + '<em>d</em>' + 'harris',
        home: 'home',
        projects: 'projects',
        design: 'design',
        about: 'about'
    }

    const Logo = () => {
        return (
            <LogoContainer>
                <span dangerouslySetInnerHTML={{__html: homeHeading.default}}/>
            </LogoContainer>
        );
    }

    return (
       <DesktopHeader>
            <Link to={'/'}><HomeSvg/></Link>
            <Link to={'/projects'}><ProjectsSvg/></Link>
            <Link to={'/design'}><DesignSvg/></Link>
            <Link to={'/about'}><AboutSvg/></Link>
            <Logo/>
       </DesktopHeader>
    );
}

export default HeaderDesktop;

I have removed attempts at implementing a fade / changing the text on hover so as to keep this post clear. Everything I have tried before posting has not been pretty!

Note: LogoContainer & DesktopHeader and the Svgs are Styled Components.

Thank you for your time.


Solution

  • Store heading value in a state and then update the heading with relevant value on onMouseEnter and onMouseLeave.

    Example:

    
    import {useState} from "react";
    
    const HeaderDesktop = () => {
        
        const defaultHeading = 'edwin' + '<em>d</em>' + 'harris'
        const [heading, setHeading] = useState(defaultHeading)
    
        const Logo = ({heading}) => {
            return (
                <LogoContainer>
                    <span dangerouslySetInnerHTML={{__html: heading}}/>
                </LogoContainer>
            );
        }
    
        const setDefaultPageHeading = () => setHeading(defaultHeading)
    
        return (
            <DesktopHeader>
                <Link to={'/'}><HomeSvg/></Link>
                <Link to={'/projects'}>
                    <span
                        onMouseEnter={()=> setHeading('projects')}
                        onMouseLeave={setDefaultPageHeading}
                    >
                        <ProjectsSvg/>
                    </span>
                </Link>
                <Link to={'/design'}>
                    <span
                        onMouseEnter={()=> setHeading('design')}
                        onMouseLeave={setDefaultPageHeading}
                    >
                        <DesignSvg/>
                    </span>
                </Link>
                <Link to={'/about'}>
                    <span
                        onMouseEnter={()=> setHeading('about')}
                        onMouseLeave={setDefaultPageHeading}
                    >
                       <AboutSvg/>
                    </span>
                </Link>
                <Logo heading={heading}/>
            </DesktopHeader>
        );
    }
    
    export default HeaderDesktop;