You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React初始渲染时用useRef获取DOM节点值报错,求解决方案

解决React子组件接收ref报错的问题

错误提示“ref不是prop,尝试访问它会返回undefined”的核心原因是:ref是React的特殊属性,不会被纳入组件的props集合中,所以你在FormRow里直接解构ref属性时,实际上拿不到父组件传递的ref值,自然会报错。

下面提供两种可行的解决方案:

方案一:使用React.forwardRef转发Ref

这是React官方推荐的、用于向子组件传递ref的标准方式,适合需要直接获取子组件内部DOM元素的场景。

修改FormRow组件:

import React, { forwardRef } from "react";

// 用forwardRef包裹组件,接收props和ref两个参数
const FormRow = forwardRef(({
  type,
  name,
  labelText,
  defaultValue = "",
  onChange,
  onBlur,
  max,
}, ref) => {
  return (
    <div className="form-row">
      <label htmlFor={name} className="form-label">
        {labelText || name}
      </label>
      <input
        autoComplete="off"
        type={type}
        id={name}
        name={name}
        className="form-input"
        defaultValue={defaultValue}
        required
        onChange={onChange}
        onBlur={onBlur}
        max={max}
        min="0"
        ref={ref} // 将转发的ref绑定到input元素上
      />
    </div>
  );
});

export default FormRow;

修正AddProject组件的读取逻辑:

你当前打印的是ref对象本身,需要访问current属性才能拿到DOM元素,且要等组件挂载后再读取(通过空依赖的useEffect确保只执行一次):

const AddProject = () => {
  const refContainer = useRef(null);
  
  useEffect(() => {
    // 组件挂载后,ref.current才会指向input元素
    console.log(refContainer.current?.value); // 读取输入框的值
  }, []);

  return (
    <Wrapper>
            <Form>
              <FormRow
                type="number"
                name="noOfChemicals"
                labelText="Number of Chemicals / Work Items"
                onChange={handleChange}
                defaultValue="1"
                ref={refContainer} // 这里用法不变
              />
            </Form>
    </Wrapper>
  );
};
export default AddProject;

方案二:将Ref作为普通Prop传递(重命名)

如果不想用forwardRef,可以把ref重命名为普通prop(比如inputRef),绕过React对ref属性的特殊处理。

修改AddProject组件的传参:

<FormRow
  type="number"
  name="noOfChemicals"
  labelText="Number of Chemicals / Work Items"
  onChange={handleChange}
  defaultValue="1"
  inputRef={refContainer} // 把ref改名为inputRef传递
/>

修改FormRow组件:

import React from "react";

const FormRow = ({
  type,
  name,
  labelText,
  defaultValue = "",
  onChange,
  onBlur,
  max,
  inputRef, // 解构重命名后的prop
}) => {
  return (
    <div className="form-row">
      <label htmlFor={name} className="form-label">
        {labelText || name}
      </label>
      <input
        autoComplete="off"
        type={type}
        id={name}
        name={name}
        className="form-input"
        defaultValue={defaultValue}
        required
        onChange={onChange}
        onBlur={onBlur}
        max={max}
        min="0"
        ref={inputRef} // 绑定到input元素
      />
    </div>
  );
};

export default FormRow;

同样修正读取逻辑:

和方案一一致,在挂载后的useEffect里访问refContainer.current?.value即可获取输入框的值。

内容的提问来源于stack exchange,提问作者Blob

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 21:17:24