React类组件向函数子组件传递ref的focus方法报错如何解决
问题根因
- 报错核心原因分两类:一是你代码中应该指向父组件实例的
this被误写/被替换为了事件对象e,二是this.usernameRef.current指向的不是原生input DOM元素,导致不存在focus方法。 - 子组件内的a标签写法不规范:a标签不属于可自闭和元素,且
href="#"的默认点击行为会触发页面锚点跳转,可能打断ref方法的正常调用。 - 如果你把
usernameRef直接绑定到了自定义组件上,没有通过forwardRef转发ref到内部input元素,也会导致current指向的是组件实例而非DOM节点,找不到focus方法。
正确实现方案
- 修正子组件a标签的写法,阻止默认点击行为:
// 子组件内调整点击事件逻辑 <a href="#" onClick={(e) => { e.preventDefault() onClick() }}>触发输入框聚焦</a>
- 父组件传递回调时增加非空校验,避免ref未挂载时报错:
你可以选择两种写法:
- 内联箭头函数写法(适合简单场景)
<ChildComponent onClick={() => this.usernameRef.current?.focus()} /> // 不支持可选链语法的话改为普通判断 <ChildComponent onClick={() => this.usernameRef.current && this.usernameRef.current.focus()} />
- 预定义实例方法写法(避免每次渲染生成新函数,性能更优)
// 父组件类内部定义方法 focusUsernameInput = () => { if (this.usernameRef.current) { this.usernameRef.current.focus() } } // 传递给子组件 <ChildComponent onClick={this.focusUsernameInput} />
- 如果你是把ref绑定在自定义组件上,需要用
forwardRef转发ref到内部input:
// 自定义输入组件用forwardRef包裹 const MyInput = React.forwardRef((props, ref) => { return <input ref={ref} {...props} /> }) // 父组件绑定ref即可拿到内部input的DOM节点 <MyInput ref={this.usernameRef} />
内容的提问来源于stack exchange,提问作者user1702965
相关产品推荐
相关产品推荐

