React向子组件传事件函数报MouseEventHandler类型不匹配错误
问题根因
该TypeScript报错和返回值类型void的声明没有关系,是两处类型不匹配问题叠加导致的:
- 父组件实际传给子组件的
hideCard是已经绑定了当前卡片ID的无参函数(即() => hideCard(card.id)),但ChildCardProps中却将其类型定义为「接收number类型参数的函数」,父子组件的prop类型首先就不一致。 - 子组件直接将
hideCard属性赋值给button的onClick事件,而React规定onClick接收的处理函数必须符合MouseEventHandler<HTMLButtonElement>签名,该类型函数的第一个参数是鼠标事件对象,和你定义的函数签名完全不匹配,因此触发类型警告。
正确类型定义与实现
根据你的业务场景(父组件提前绑定卡片ID),只需要修正类型定义、调整事件绑定写法即可:
const Cards = () => { // 给入参添加类型,避免隐式any警告 const hideCard = (cardId: number) => { console.log(`card ${cardId} should be hidden`); }; return ( <> <ChildCard hideCard={() => hideCard(card.id)} /> </> ) } interface ChildCardProps { // 父组件传入的是无参函数,对应修改类型 hideCard: () => void; } const ChildCard = ({hideCard}: ChildCardProps) => { return ( <> <button // 用箭头函数包裹调用,符合onClick的事件签名要求 onClick={() => hideCard()} type="button">Hide this card </button> </> ) }
如果你的场景是子组件内部持有卡片ID、需要在触发点击时才把ID传给父组件,可以参考第二种写法:
const Cards = () => { const hideCard = (cardId: number) => { console.log(`card ${cardId} should be hidden`); }; return ( <> {/* 直接传递原函数,不提前绑定参数 */} <ChildCard hideCard={hideCard} cardId={card.id} /> </> ) } interface ChildCardProps { hideCard: (cardId: number) => void; cardId: number; } const ChildCard = ({hideCard, cardId}: ChildCardProps) => { return ( <> <button // 点击触发时再传入卡片ID,不需要使用事件对象可以省略e参数 onClick={() => hideCard(cardId)} type="button">Hide this card </button> </> ) }
- 通用注意点:不要把带自定义参数的业务函数直接赋值给原生事件属性,只要函数签名和事件要求的
MouseEventHandler不匹配就会报类型错误。用内联箭头函数包裹一层再调用业务函数,既可以自由传递自定义参数,也能符合事件的类型约束。
内容的提问来源于stack exchange,提问作者randombits
相关产品推荐
相关产品推荐

