You need to enable JavaScript to run this app. React使用forwardRef封装可复用input组件时无法获取ref值如何解决?
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.21 08:15:03