admin管理员组

文章数量:1278859

I have a custom Card ponent, which gets an "onClick" type, to handle clicking like so:

import React from 'react';
import styles from './card.module.css';

interface Card {
    onClick: React.MouseEventHandler<HTMLDivElement>;
}

const Card: React.FC<Card> = ({ children }) => {
    return <div className={styles.card}>{children}</div>;
};

export default Card;

I'm using Card to pose another ponent called PostCard like so:

import React from 'react';
import Card from '../Card';
import styles from './postcard.module.css';
import { useRouter } from 'next/router';

type PostCard = {
    title: string;
    description: string;
    slug: string;
};

const PostCard: React.FC<PostCard> = ({ title, description, slug }) => {
    const router = useRouter();

    const handleClick: React.MouseEventHandler<HTMLDivElement> = (e) => {
        console.log('here');
        e.preventDefault();
        router.push('/blog/[slug]', `/blog/${slug}`, { slug });
    };
    return (
        <Card onClick={handleClick}>
            <h2 className={styles.title}>{title}</h2>
            <p className={styles.paragraph}>{description}</p>
        </Card>
    );
};

export default PostCard;

When PostCard is clicked, I want it to use the router function from next.js and push the page to a new page. How ever, when I click on PostCard nothing happens. What's going on? Nothing is printed to the console from handleClick so I'm pretty sure the click isn't being registered by the Card ponent. Should I be passing the onClick function to the Card ponent?

I have a custom Card ponent, which gets an "onClick" type, to handle clicking like so:

import React from 'react';
import styles from './card.module.css';

interface Card {
    onClick: React.MouseEventHandler<HTMLDivElement>;
}

const Card: React.FC<Card> = ({ children }) => {
    return <div className={styles.card}>{children}</div>;
};

export default Card;

I'm using Card to pose another ponent called PostCard like so:

import React from 'react';
import Card from '../Card';
import styles from './postcard.module.css';
import { useRouter } from 'next/router';

type PostCard = {
    title: string;
    description: string;
    slug: string;
};

const PostCard: React.FC<PostCard> = ({ title, description, slug }) => {
    const router = useRouter();

    const handleClick: React.MouseEventHandler<HTMLDivElement> = (e) => {
        console.log('here');
        e.preventDefault();
        router.push('/blog/[slug]', `/blog/${slug}`, { slug });
    };
    return (
        <Card onClick={handleClick}>
            <h2 className={styles.title}>{title}</h2>
            <p className={styles.paragraph}>{description}</p>
        </Card>
    );
};

export default PostCard;

When PostCard is clicked, I want it to use the router function from next.js and push the page to a new page. How ever, when I click on PostCard nothing happens. What's going on? Nothing is printed to the console from handleClick so I'm pretty sure the click isn't being registered by the Card ponent. Should I be passing the onClick function to the Card ponent?

Share Improve this question asked Jul 5, 2020 at 16:57 P4nd4b0b3r1n0P4nd4b0b3r1n0 2,4015 gold badges28 silver badges36 bronze badges 1
  • Am just curious what does e.preventDefault(); stop on a HTMLDivElement? – Klem Lloyd Mwenya Commented Jan 23, 2023 at 21:59
Add a ment  | 

2 Answers 2

Reset to default 4

The onClick needs to be on the div tag instead on Card, here you are sending the handleClick function as a prop to the Card ponent (onClick), so you need to accept that prop in the Card ponent and put the function on onClick of the div rendered.

In PostCard

return (
        <Card handleClick={handleClick}>
            <h2 className={styles.title}>{title}</h2>
            <p className={styles.paragraph}>{description}</p>
        </Card>
    );

We can send prop as handleClick instead of onClick to avoid confusion.

And in the Card ponent

const Card: React.FC<Card> = ({ children, handleClick }) => {
    return <div onClick={handleClick} className={styles.card}>{children}</div>;
};

You're using onClick on the Card but the Card returns a div with the children and the onClick prop is not used anywhere.

Try this:

<Card clicked={handleClick}>
    <h2 className={styles.title}>{title}</h2>
    <p className={styles.paragraph}>{description}</p>
</Card>


const Card: React.FC<Card> = ({ children, clicked }) => {
    return <div onClick={clicked} className={styles.card}>{children}</div>;
};

The interface should also be changed:

interface Card {
    clicked: React.MouseEventHandler<HTMLDivElement>;
}

本文标签: javascriptHow to handle click events on divs with React and TypescriptStack Overflow