React使用forwardRef封装可复用input组件时无法获取ref值如何解决?
问题原因
React的forwardRef API的渲染函数参数规则是,第一个参数接收组件的props,第二个参数才接收透传的ref对象。你现在错误地将ref放到第一个props参数里解构,导致实际拿到的ref是undefined,最终上层的textRef没有绑定到真实的input DOM元素上,所以读取值时始终为undefined。
修复方案
1. 修改inputField.js代码
把ref从props里移到第二个参数的位置:
import React, { forwardRef } from 'react'; // 第二个参数接收透传的ref,不要放在第一个props里解构 const InputField = forwardRef( ({ value, label, name, placeholder, type, onChange }, ref) => ( <> {label && <label htmlFor='input-field'>{label}</label>} <input type={type} value={value} name={name} className='bg-customBlack-light hover:bg-customBlackLighter-light w-full text-xs p-4 mb-6 rounded-md outline-none transition duration-150 ease-in-out' placeholder={placeholder} onChange={onChange} ref={ref} /> </> ) ); // 建议加displayName方便调试 InputField.displayName = 'InputField'; export default InputField;
2. 补充login.js的密码切换逻辑
修复ref绑定后,你就可以通过textRef.current拿到真实input DOM,修改它的type属性实现明文/密文切换,示例代码如下:
import { useState, useRef } from 'react'; const Login = ({ history }) => { const textRef = useRef(); // 新增状态记录密码是否显示 const [showPwd, setShowPwd] = useState(false); const togglePwdVisible = () => { const newStatus = !showPwd; setShowPwd(newStatus); // 直接修改input的type属性 textRef.current.type = newStatus ? 'text' : 'password'; // 获取输入框值可以直接取textRef.current.value console.log(textRef.current.value); }; // 补充你原本的业务逻辑即可 const [userInfo, setUserInfo] = useState({password: ''}); const handleChange = (e) => { setUserInfo(prev => ({...prev, [e.target.name]: e.target.value})) }; const handleSubmit = (e) => { e.preventDefault(); // 提交逻辑 } return ( <FormContainer> <form noValidate onSubmit={handleSubmit} className='w-10/12 h-2/4 mx-auto flex flex-col justify-center' > <div className='form-group w-full relative'> <InputField type='password' placeholder='Password' name='password' ref={textRef} value={userInfo.password} onChange={handleChange} /> <FontAwesomeIcon icon={faEye} className='absolute top-4 right-4 opacity-60' onClick={togglePwdVisible} /> </div> </form> </FormContainer> ); };
可选优化
如果你不需要操作DOM,也可以直接通过状态控制input的type,不需要用ref:给InputField传的type属性直接绑定showPwd ? 'text' : 'password'即可,实现方式更符合React的状态驱动理念,代码更简洁。
内容的提问来源于stack exchange,提问作者rjc30
相关产品推荐
相关产品推荐

