React自定义组件传ref报IntrinsicAttributes类型不兼容错误如何解决
问题原因
你遇到的报错是因为函数式自定义组件默认不支持直接接收ref属性,ref是React的特殊属性,不会被当作普通props传递,你定义的content类型里也没有包含ref相关声明,所以TypeScript会抛出类型不匹配错误。同时要支持className、name这类原生DOM属性,需要扩展你的props类型继承原生HTML属性定义。
解决方案
使用React内置的React.forwardRefAPI包裹你的自定义组件,同时扩展props类型支持原生属性,具体修改如下:
1. 修改Box.tsx代码
import React from 'react'; import './Box.css'; import Draggable from 'react-draggable'; // 扩展props类型,继承div的所有原生属性,支持className、name等原生属性传递 export type ContentProps = { letter: string, draggable: number } & React.HTMLAttributes<HTMLDivElement> // 用forwardRef包裹组件,第一个泛型指定ref指向的DOM元素类型,第二个是props类型 export const Box = React.forwardRef<HTMLDivElement, ContentProps>((props, ref) => { // 拆分自定义属性和原生属性 const { letter, draggable, ...nativeProps } = props; if(draggable) { return ( <Draggable> {/* 透传ref和原生属性给根div */} <div ref={ref} className="box box-drag" {...nativeProps}> <span className="box-content"> {letter} </span> </div> </Draggable> ); } return ( {/* 透传ref和原生属性给根div */} <div ref={ref} className="box" {...nativeProps}> <span className="box-content" ref={el => {console.log(el?.getBoundingClientRect());}}> {letter} </span> </div> ); }); // 可选配置,方便React DevTools识别组件名称 Box.displayName = 'Box';
2. 修改Content.tsx的ref定义
给ref指定明确的元素类型,避免unknown类型报错:
// 指定ref指向HTMLDivElement类型,和Box组件的ref类型匹配 const test = React.createRef<HTMLDivElement>();
方案说明
React.forwardRef会将外部传入的ref作为第二个参数传递给组件函数,你可以自由绑定到内部任意需要暴露的DOM元素上,实现自定义组件和原生元素一致的ref传递体验。- 继承
React.HTMLAttributes<HTMLDivElement>后,所有div支持的原生属性都可以直接传递给Box组件,TypeScript会自动做类型校验,不需要手动逐个声明。如果你的组件根元素是其他类型(比如span、button),替换对应的HTML元素类型即可。
内容的提问来源于stack exchange,提问作者user14399919
相关产品推荐
相关产品推荐

