i18next 8.4.3中forwardRef结合translate无法获取子组件span元素ref怎么办
问题根源
react-i18next 8.4.3版本的translate高阶组件开启forwardRef: true时,会自动为被包裹组件实现ref转发逻辑。当前代码额外手动给ChildComponent套了一层React.forwardRef,造成两层ref转发嵌套,父组件传入的ref被i18n的HOC层拦截,最终拿到的是Translate包装对象而非内部span DOM。
可行解决方案
以下两种方案选其一即可,优先推荐第一种,兼容性最好无版本坑。
方案1:使用自定义prop传递ref(最稳妥)
ref是React的特殊属性,默认不会通过普通props透传,只要换一个普通自定义属性名传递ref,就能完全绕开HOC对ref的特殊拦截逻辑,不需要依赖translate的forwardRef配置。
代码调整如下:// 子组件:不需要手动包forwardRef,从普通props中取传递的ref const ChildComponent = (props) => { const { spanRef, ...otherProps } = props; // ...其他业务逻辑 return ( <span ref={spanRef} {...otherProps}></span> // ...其他节点 ) } // 不需要开启forwardRef配置 export default translate('translations')(ChildComponent);父组件使用时直接传入自定义的ref属性即可:
import { useRef, useEffect } from 'react'; const ParentComponent = () => { const targetSpanRef = useRef(null); useEffect(() => { // targetSpanRef.current 就是目标span DOM元素 console.log(targetSpanRef.current); }, []); return <ChildComponent spanRef={targetSpanRef} /> }方案2:移除手动嵌套的forwardRef,复用translate自带的转发逻辑
去掉自写的React.forwardRef包裹层,直接让translate的forwardRef配置接管ref转发,HOC会自动把父组件传入的ref作为第二个参数传给组件函数。
代码调整如下:// 不要手动包forwardRef,组件函数直接接收第二个参数作为转发的ref const ChildComponent = (props, ref) => { // ...其他业务逻辑 return ( <span ref={ref}></span> // ...其他节点 ) } // 保留forwardRef:true配置即可 export default translate('translations', { forwardRef: true })(ChildComponent);父组件使用时直接传标准ref属性即可拿到span DOM:
const ParentComponent = () => { const targetSpanRef = useRef(null); return <ChildComponent ref={targetSpanRef} /> }
提示:如果ChildComponent是类组件,方案2拿到的ref默认是类组件实例,需要在类组件内部把ref绑定到目标span节点,或者通过实例属性暴露DOM,不推荐使用
findDOMNode获取,严格模式下会抛出警告。
内容的提问来源于stack exchange,提问作者feelingreat
相关产品推荐
相关产品推荐

