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
相关产品推荐
相关产品推荐

