如何为React中不受控制的第三方组件内按钮添加Ref并实现主动聚焦
解决方案
场景1:可修改ExternalButtonComponent源码
如果可以和提供组件的团队协商修改组件代码,推荐使用React官方的**Ref转发(Forward Ref)**方案,这是最规范的实现方式:
首先修改ExternalButtonComponent.js代码,用forwardRef将父组件传入的ref透传到内部的button元素:
import { forwardRef } from 'react'; const ExternalButtonComponent = forwardRef((props, ref) => { return <div><button ref={ref} id="btn-external">This is a button</button></div> }); export default ExternalButtonComponent;
然后修改你自己的myCode.js,给外部组件绑定ref,点击时调用focus方法即可:
import { createRef } from 'react'; class YourComponent extends React.Component { // 声明ref存储外部按钮的引用 externalBtnRef = createRef(); focusExternalButton() { this.externalBtnRef.current?.focus(); } render() { return ( <div> <ExternalButtonComponent ref={this.externalBtnRef}/> <button onClick={this.focusExternalButton.bind(this)}>submit</button> </div> ) } }
如果使用函数组件,写法如下:
import { useRef } from 'react'; function YourComponent() { const externalBtnRef = useRef(null); const focusExternalButton = () => { externalBtnRef.current?.focus(); } return ( <div> <ExternalButtonComponent ref={externalBtnRef}/> <button onClick={focusExternalButton}>submit</button> </div> ) }
场景2:无法修改ExternalButtonComponent源码
如果其他团队不接受修改组件的需求,可以用以下两种临时方案实现:
- 方案1:直接通过id获取元素(你的场景里按钮已经绑定了固定id,实现成本最低)
修改你的focusExternalButton方法即可:
focusExternalButton() { document.getElementById('btn-external')?.focus(); }
注意:如果页面中会渲染多个ExternalButtonComponent实例,会出现id重复的问题,该方案不适用。
- 方案2:通过父容器DOM查询内部按钮
给外部组件包裹一层容器,通过容器查询内部的button元素,不受id重复影响:
// myCode.js externalBtnContainer = createRef(); focusExternalButton() { this.externalBtnContainer.current?.querySelector('button')?.focus(); } render() { return ( <div> <div ref={this.externalBtnContainer}> <ExternalButtonComponent/> </div> <button onClick={this.focusExternalButton.bind(this)}>submit</button> </div> ) }
该方案只要组件内部的DOM结构不变就能正常运行。
内容的提问来源于stack exchange,提问作者Neon
相关产品推荐
相关产品推荐

