react-redux 中获取子组件(被包装的木偶组件)的实例

1.refs使用场景

在某些情况下,我们需要在典型数据流之外强制修改子组件,被修改的子组件可能是一个 React 组件的实例,也可能是一个 DOM 元素,例如:

  • 管理焦点,文本选择或媒体播放。
    如下面这样:
  focusTextInput() {
    // 直接使用原生 API 使 text 输入框获得焦点
    // 注意:我们通过 "current" 来访问 DOM 节点
    this.textInput.current.focus();
  }
  • 触发强制动画。
  • 集成第三方 DOM 库。

2.如何设置refs

(1)React.createRef()
  • 创建refs
class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.myRef = React.createRef();
  }
  render() {
    return <div ref={this.myRef} />;
  }
}
  • 访问refs
    当 ref 被传递给 render 中的元素时,对该节点的引用可以在 ref 的 current 属性中被访问。
const node = this.myRef.current;

ref 的值根据节点的类型而有所不同:

  • 当 ref 属性用于 HTML 元素时,构造函数中使用 React.createRef() 创建的 ref 接收底层 DOM 元素作为其 current 属性。
  • 当 ref 属性用于自定义 class 组件时,ref 对象接收组件的挂载实例作为其 current 属性。
  • 你不能在函数组件上使用 ref 属性,因为他们没有实例
(2)回调refs

使用 回调 refs 需要将回调函数传递给 React元素 的 ref 属性。这个函数接受 React 组件实例 或 HTML DOM 元素作为参数,将其挂载到实例属性上。示例:

import React from 'react';

export default class MyInput extends React.Component {
    constructor(props) {
        super(props);
        this.inputRef = null;
        this.setTextInputRef = (ele) => {
            this.inputRef = ele;
        }
    }

    componentDidMount() {
        this.inputRef && this.inputRef.focus();
    }
    render() {
        return (
            <input type="text" ref={this.setTextInputRef}/>
        )
    }
}

React 会在组件挂载时,调用 ref 回调函数并传入 DOM元素(或React实例),当卸载时调用它并传入 null。在 componentDidMount 或 componentDidUpdate 触发前,React 会保证 Refs 一定是最新的。

3.子组件未被connect()包装成容器组件

就比如下面这个CustomTextInput组件,用 ref 的 current 属性中被访问。

class AutoFocusTextInput extends React.Component {
  constructor(props) {
    super(props);
    this.textInput = React.createRef();
  }

  componentDidMount() {
    this.textInput.current.focusTextInput();
  }

  render() {
    return (
      <CustomTextInput ref={this.textInput} />
    );
  }
}

CustomTextInput组件

class CustomTextInput extends React.Component {
  // ...
}

4.子组件被connect()包装成了容器组件,用current访问不行了。

原因是:ref上没有current属性了。

  • 如何获取呢?
    connect 有四个参数,如果我们想要在父组件中子组件(木偶组件)的实例,那么需要设置第四个参数 optionswithRef 为 true。随后可以在父组件中通过容器组件实例的 getWrappedInstance() 方法获取到木偶组件(被包装的组件)的实例。

AutoComplete子组件

export default connect(mapStateToProps, mapDispatchToProps, null, { withRef: true })(AutoComplete);

Filter父组件

<AutoComplete
	getInputValue={getInputValue}
	options={options}
	getData={getData}
	updateSelect={this.updateSelect}
	ref = {ref => this.triggerEmptyValue = ref}
/> 

Filter父组件中获取AutoComplete组件实例,并且调用其方法

this.triggerEmptyValue.getWrappedInstance().emptyInputValue();
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值