【问题记录】React使用connect后,ref.current为null

15 篇文章 1 订阅

问题

在用React开发项目的过程中,遇到一个问题,使用connect连接低阶组件包装成高阶组件HOC后,父组件通通过ref调用子组件方法时,提示xxxRef.currentnull的错误。同时控制台Console报以下警告:

Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?

代码如下:

// 子组件
// 通过connect方式连接为高阶组件
export default connect(
    mapStateToProps,
)(ComboSelectorForm);
// 父组件
constructor(props: IComboSelectorListProps | Readonly<IComboSelectorListProps>) {
    super(props);
    // ...
    this.formRef = React.createRef();
    // ...
}
// 组件挂载在formRef上
<ComboSelectorForm
    ref={this.formRef}
    id={this.state.id}
    onSaveSuccess={this.handleSaveSuccess}
>
</ComboSelectorForm>

// 调用子组件方法
this.formRef.current.methodName();

父组件调用子组件方法后,报以下错误

TypeError: Cannot read properties of null (reading 'methodName')

解析

React的高阶组件HOC,可以理解成在低阶组件上进行一些封装。高阶组件HOC如果不做一些特殊处理,是无法直接访问低阶组件实例的,要想通过ref访问低阶组件实例,调用connect时,需要传递参数{forwardRef : true}
connect方法有四个参数,官方文档是这样说明的:

  1. mapStateToProps?: Function
  2. mapDispatchToProps?: Function | Object
  3. mergeProps?: Function
  4. options?: Object

对于前面三个参数先不展开来讲解,主要第四个options参数,有以下几个属性:

{
  context?: Object,
  pure?: boolean,
  areStatesEqual?: Function,
  areOwnPropsEqual?: Function,
  areStatePropsEqual?: Function,
  areMergedPropsEqual?: Function,
  forwardRef?: boolean,
}

其中最后一个参数forwardRef正是我们的主角,官方文档里这样解释:

If {forwardRef : true} has been passed to connect, adding a ref to the connected wrapper component will actually return the instance of the wrapped component.

当该参数forwardRef 设置为true时,包裹组件(wrapper component )的ref属性将会实际返回被包裹组件(wrapped component)实例。OS:原谅我翻译水平有限。(>_<)

最终解决方案

直接上代码:

// 子组件
// 通过connect方式连接为高阶组件
export default connect(
    mapStateToProps,
    null,	// 新加参数
    null,	// 新加参数
    { forwardRef: true }	// 新加参数
)(ComboSelectorForm);
// 父组件,与之前代码一致
constructor(props: IComboSelectorListProps | Readonly<IComboSelectorListProps>) {
    super(props);
    // ...
    this.formRef = React.createRef();
    // ...
}
// 组件挂载在formRef上
<ComboSelectorForm
    ref={this.formRef}
    id={this.state.id}
    onSaveSuccess={this.handleSaveSuccess}
>
</ComboSelectorForm>

// 调用子组件方法
this.formRef.current.methodName();

通过以上改造后,父组件能够正常访问ref实例。😄


扩展阅读:
React + Antd实现动态切换主题功能
React + Antd实现动态切换主题功能之二(默认主题与暗黑色主题切换)
React + Router + Antd实现多标签页功能(具体代码实现)

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值