在forwardRef函数组件中使用Ref获取Input元素值的方法
自定义输入组件获取值的解决办法
问题根源
你传入的ref不是普通的Ref对象,而是React Hook Form的回调式Ref(从你打印的代码能看出来,这是RHF register方法返回的回调函数)。这类Ref本身是个函数,没有current属性,所以ref.current...肯定用不了。
解决方案:本地Ref + 转发外部Ref
在组件内部创建一个本地Ref来捕获input元素,同时把这个本地Ref传递给外部的回调Ref,既满足自己获取值的需求,也不影响表单库的逻辑。
修改后的完整代码
import { forwardRef, useEffect, useRef } from 'react'; // 定义组件Props类型 type Props = React.InputHTMLAttributes<HTMLInputElement>; export const CustomInput = forwardRef<HTMLInputElement, Props>((props, externalRef) => { // 本地Ref,专门用来获取当前input元素 const localInputRef = useRef<HTMLInputElement>(null); useEffect(() => { // 组件挂载时获取input值 if (localInputRef.current) { console.log('Input当前值:', localInputRef.current.value); } }, []); // 处理外部传入的Ref:兼容函数式Ref和对象式Ref useEffect(() => { if (!externalRef) return; if (typeof externalRef === 'function') { // 如果是回调式Ref(比如RHF的register),调用它传入本地Ref的current externalRef(localInputRef.current); } else { // 如果是普通对象Ref,把本地Ref的current赋值给它 externalRef.current = localInputRef.current; } // 组件卸载时清理Ref return () => { if (typeof externalRef === 'function') { externalRef(null); } else { externalRef.current = null; } }; }, [externalRef]); return <input ref={localInputRef} {...props} />; });
原理说明
- 本地
localInputRef是标准的MutableRefObject,可以正常通过current访问input的value等属性。 - 额外的
useEffect用来同步外部Ref:不管外部传的是回调函数还是普通Ref对象,都能把input元素的引用传递过去,保证React Hook Form的表单注册逻辑正常工作。
简化方案(仅在输入时获取值)
如果不需要在组件挂载时就获取值,只是想在用户输入时拿到最新值,可以直接复用input的onChange事件:
export const CustomInput = forwardRef<HTMLInputElement, Props>((props, ref) => { const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => { console.log('当前输入值:', e.target.value); // 别忘了调用原props的onChange,避免覆盖外部逻辑 props.onChange?.(e); }; return <input ref={ref} {...props} onChange={handleInputChange} />; });
内容的提问来源于stack exchange,提问作者NGI
相关产品推荐
相关产品推荐

