如何将React forwardRef与Redux connect正确结合使用?
解决React forwardRef与Redux connect结合的问题
这个问题我之前也碰到过!其实核心原因是Redux的connect默认会创建一个高阶组件(HOC),外部传入的ref会指向这个HOC,而不是你真正想要的MyComponent。要解决这个问题,我们需要让connect允许ref穿透到内部组件,结合forwardRef一起工作,具体有两种常用方法:
方法一:利用Redux connect的forwardRef选项(推荐)
从Redux v7.1.0开始,connect支持第四个参数options,其中的forwardRef属性设为true后,connect会将外部传入的ref传递给被包裹的组件。结合你的场景,代码可以这样写:
import React from 'react'; import { connect } from 'react-redux'; // 1. 用forwardRef把外部ref传递给MyComponent的innerRef const WrappedMyComponent = React.forwardRef((props, ref) => { return <MyComponent {...props} innerRef={ref} />; }); // 2. 用connect包裹时开启forwardRef选项,让ref能穿透到内部组件 export default connect( mapStateToProps, null, null, { forwardRef: true } // 关键:开启ref穿透 )(WrappedMyComponent);
这样当父组件使用ref时,它会直接指向MyComponent的实例,完美实现你想要的效果。
方法二:自定义暴露的ref内容(用useImperativeHandle)
如果你需要自定义ref暴露给外部的方法或属性,可以结合useImperativeHandle来实现:
import React, { forwardRef, useImperativeHandle, useRef } from 'react'; import { connect } from 'react-redux'; const WrappedMyComponent = forwardRef((props, ref) => { const innerComponentRef = useRef(); // 自定义外部ref能访问的内容 useImperativeHandle(ref, () => ({ // 比如暴露MyComponent的某个方法 triggerInnerMethod: () => innerComponentRef.current.someInnerMethod(), // 或者暴露某个属性 getInnerState: () => innerComponentRef.current.someState })); return <MyComponent {...props} innerRef={innerComponentRef} />; }); export default connect( mapStateToProps, null, null, { forwardRef: true } )(WrappedMyComponent);
这种方式适合你不需要暴露整个组件实例,只想开放特定功能的场景。
为什么你的原写法不生效?
你之前的写法是把forwardRef包装后的组件传给connect,但因为connect默认不会传递ref到内部组件,所以外部传入的ref最终指向的是connect生成的HOC,而不是MyComponent,自然无法正常工作。开启forwardRef选项后,connect才会把ref传递给内部的forwardRef组件,进而传递到MyComponent的innerRef。
内容的提问来源于stack exchange,提问作者darKnight
相关产品推荐
相关产品推荐

