一起学习网 一起学习网


记录React使用connect后,ref.current为null问题及解决

网络编程 React使用connect,ref.current为null,使用connect后ref.current为null 06-18

问题

在用React开发项目的过程中,遇到一个问题,使用connect连接低阶组件包装成高阶组件HOC后,父组件通用ref调用子组件方法时,提示xxxRef.current为null的错误。

代码如下:

// 子组件// 通过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方法有四个参数,官方文档是这样说明的:

  • mapStateToProps?: Function
  • mapDispatchToProps?: Function | Object
  • mergeProps?: Function
  • 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实例。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。


编辑:一起学习网

标签:组件,参数,低阶,高阶,方法