React中使用forwardRef时无法声明自定义属性的问题
React中使用forwardRef时自定义属性报错的解决方法
问题根源
使用forwardRef封装组件时传递自定义属性(如someval)触发类型错误:
someval is not assignable to IntrinsicAttributes & RefAttributes
本质是未为子组件的props定义明确的TypeScript类型,导致TS无法识别自定义属性,只能校验默认的IntrinsicAttributes和RefAttributes。
解决方案
1. 定义Props和Ref的类型接口
先明确子组件接收的props类型,以及通过useImperativeHandle暴露给父组件的ref方法类型:
// 子组件接收的props类型 interface MyInputProps { someval: number; // 可添加其他自定义属性 } // ref暴露给父组件的方法类型 interface MyInputHandle { focus(): void; scrollIntoView(): void; }
2. 为forwardRef指定泛型类型
在forwardRef中通过泛型声明ref类型和props类型,让TS能够正确校验属性:
import React, { forwardRef, useRef, useImperativeHandle } from 'react'; const MyInput = forwardRef<MyInputHandle, MyInputProps>((props, ref) => { const inputRef = useRef<HTMLDivElement>(null); useImperativeHandle( ref, () => ({ focus() { console.log("calling focus"); inputRef.current?.focus(); }, scrollIntoView() { console.log("calling scroll"); inputRef.current?.scrollIntoView(); }, }), [] ); // 可直接使用自定义属性props.someval console.log('当前someval值:', props.someval); return <div ref={inputRef} />; }); export default MyInput;
3. 父组件优化ref类型
父组件中为useRef指定对应的类型,避免null安全问题:
import React, { useRef, useState } from 'react'; import MyInput from './MyInput'; import Button from './Button'; // 假设Button组件已定义 export const Recognizer: React.FunctionComponent = () => { // 指定ref类型为MyInputHandle | null const ref = useRef<MyInputHandle>(null); const handleClick = () => { // 使用可选链避免null报错 ref.current?.focus(); }; const [someval, setSomeVal] = useState(1); return ( <div> <MyInput someval={someval} ref={ref} /> <Button onClick={handleClick}>test</Button> </div> ); };
额外说明
如果是纯JavaScript项目,不会出现该类型报错,但仍建议通过JSDoc注释明确props类型,提升代码可读性:
/** * @param {Object} props * @param {number} props.someval * @param {React.Ref} ref */ const MyInput = forwardRef(function MyInput(props, ref) { // ...组件逻辑 });
内容的提问来源于stack exchange,提问作者patrick
相关产品推荐
相关产品推荐

