0

consider the code below:


interface ILink {
    clicked: (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => void;
    Icon: OverridableComponent<SvgIconTypeMap<{}, 'svg'>>;
    children: string;
    className: string;
    color: string;
}

const Link: React.FC<ILink> = ({
    Icon,
    children,
    color,
    clicked,
    className
}) => {
    const colorClass: React.CSSProperties = { color };

    return (
        <div onClick={clicked} className={className}>
            <Icon style={colorClass} />
            <p style={colorClass}>{children}</p>
        </div>
    );
};

const Navbar: React.FC<INavbar> = ({ setPage }) => {
    const [isActive, setIsActive] = useState<string>('home');

    const handleClick = (menuItem: string) => {
        setPage(menuItem);
        setIsActive(menuItem);
    };

    return (
        <nav className='sidebarOptions'>
            <section>
                <Link
                    className='sidebarLink logo'
                    Icon={GamesIcon}
                    color={isActive === 'home' ? 'white' : 'grey'}
                    clicked={() => handleClick('home')}>
                    Better Games
                </Link>

             // ... more code
            
          </section>
        </nav>
    );
};

my problem is with 'clicked' type on ILink interface, especifically.

the principle of typescript is to define a type to a thing (a property in my case) that i am going to use, but if i try to specify the property 'clicked' as it is: () => (menuItem: string) => void, it throws a compile time error, but if specify 'clicked' as the description of onClick it works.

please, I need explanations regarding that or if you have links from articles, courses or whatever I can find to learn better about that, please, insert in.

regards.

3 Answers 3

1

The Link component doesn't actually use the value of menuItem so it doesn't need to be aware of it.

When you call a function from onClick on a div, it gets one argument which is the event. The type which you copied, React.MouseEvent<HTMLDivElement, MouseEvent>, is the very specific event type for a click action in react on a div element.

But you don't need to worry about the event type at all because you aren't using the event. An onClick function is either a function of the event: (e: Event) => {...} or it's a function which takes no arguments: () => {...}. In your case you are not using any arguments, so the type which you want for clicked in interface ILink is () => void, which means: a function that takes no arguments and returns nothing.

You might be thinking "it does take an argument, it takes menuItem", but you've already dealt with that in the handleClick function of Navbar. The Link component receives a function which already has the knowledge of the menu item included in it. This function: () => handleClick("home") takes no arguments.

So in summary you have set up everything correctly and you don't need to change anything. But if you wanted to simplify ILink, this will work:

interface ILink {
  clicked: () => void;
  ...
}
Sign up to request clarification or add additional context in comments.

Comments

0

In your code function clicked have input event is React.MouseEvent<HTMLDivElement, MouseEvent> but in your function, you pass string value so I think just change in your interface

interface ILink {
    clicked: (event: string) => void;
    Icon: OverridableComponent<SvgIconTypeMap<{}, 'svg'>>;
    children: string;
    className: string;
    color: string;
}

Comments

0

I give you 2 step only

  1. Make clicked type become (value: string) => void
  2. You can use clicked like this
    <Link
          className='sidebarLink logo'
          Icon={GamesIcon}
          color={isActive === 'home' ? 'white' : 'grey'}
          clicked={handleClick('home')}>
          Better Games
    </Link>

This approach is easier because you don't do anything from event: React.MouseEvent<HTMLDivElement, MouseEvent>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.