如何在React组件中同时使用forwardRef与自定义useRef
解决方案:同时使用React.forwardRef和useRef
你遇到的错误是因为forwardRef传入的ref参数可能是函数式ref(而非仅对象式ref),直接访问ref.current会在函数式ref场景下报错。下面提供两种可行的处理方案:
方案一:直接兼容两种ref类型
通过判断ref的类型,分别处理对象式和函数式ref,同时保留自定义的myOwnRef:
import React, { forwardRef, useRef, ChangeEvent } from 'react'; interface IExampleInputProps { value: string, onChange: (event: ChangeEvent<HTMLInputElement>) => void } const ExampleInput = forwardRef<HTMLInputElement | null, IExampleInputProps>(({value, onChange}, ref) => { const myOwnRef = useRef<HTMLInputElement | null>(null); const handleRef = (el: HTMLInputElement | null) => { // 给自定义ref赋值 myOwnRef.current = el; // 处理外部传入的ref if (typeof ref === 'function') { // 函数式ref:直接调用函数传入DOM元素 ref(el); } else if (ref != null) { // 对象式ref:给current属性赋值 ref.current = el; } }; return <input ref={handleRef} value={value} onChange={onChange}/> })
这样处理后,自定义的myOwnRef可以正常用于内部DOM操作,外部传入的无论是对象式ref还是函数式ref都能正确接收目标元素。
方案二:用useImperativeHandle暴露自定义方法(可选)
如果需要向外部暴露组件内部的自定义方法,而非直接传递DOM元素,可以结合useImperativeHandle实现:
import React, { forwardRef, useRef, useImperativeHandle, ChangeEvent } from 'react'; interface IExampleInputProps { value: string, onChange: (event: ChangeEvent<HTMLInputElement>) => void } // 定义外部可访问的方法类型 interface ExampleInputHandle { focus: () => void; // 可添加其他自定义方法 } const ExampleInput = forwardRef<ExampleInputHandle | null, IExampleInputProps>(({value, onChange}, ref) => { const myOwnRef = useRef<HTMLInputElement | null>(null); // 内部自定义方法 const focus = () => { myOwnRef.current?.focus(); }; // 将自定义方法合并到外部ref中 useImperativeHandle(ref, () => ({ focus }), []); return <input ref={myOwnRef} value={value} onChange={onChange}/> })
这种方式下,外部ref可以调用你暴露的focus方法,内部的myOwnRef依然能直接操作DOM元素。
内容的提问来源于stack exchange,提问作者xNevrroXx
相关产品推荐
相关产品推荐

