总结ref的用法

12 篇文章 0 订阅
10 篇文章 0 订阅

ref通常被用来获取DOM元素或组件实例

string类型的ref

<input type='text' ref='input' />
......
console.log(this.$refs.input)   //  <input type='text' />

$refs 是所有注册过的ref的一个集合

在react中,一般使用function类型的ref,上面的这种string类型的ref将会被废弃,因为它无法直接获取this的指向,并且当使用render回调函数的开发模式,获得ref的组件实例可能与预期不同。

function类型的ref

<WebView ref={ref => this.webview =  ref } // 将该组件赋值给webview />
console.log(this.webview)

通过React.createRef()创建ref:

this.webview = React.createRef();
// 引用
<WebView ref={this.webview} />
// 获取当前节点
console.warn(this.webview.current)

React.createRef()创建的ref对象仅仅包含current属性,表示获取的DOM元素或组件实例

useRef

useRef 返回一个可变的 ref 对象,其 .current 属性被初始化为传入的参数(initialValue)。返回的 ref 对象在组件的整个生命周期内保持不变。

即每次返回的ref对象都是一开始传入的

const refContainer = useRef(initialValue);

ref的生命周期

在React中,HostComponent、ClassComponent、ForwardRef可以赋值ref属性。ForwardRef只是将ref作为第二个参数传递下去,没有别的特殊处理。

Ref属性在ref不同的生命周期会被执行 ( fuction类型 ) 或赋值 ( {current: any}对象类型 )

ref的生命周期与react的渲染一样,可以分为 两个阶段

render阶段:

为含有ref属性的Component对应fiber添加Ref effectTag,fiber类型为HostComponent、ClassComponent、ScopeComponent

  • 对于mount,workInProgress.ref !== null,即组件首次render时存在ref属性
  • 对于update,current.ref !== workInProgress.ref,即组件更新时ref属性改变
commit阶段:

为包含Ref effectTag的fiber执行对应操作

  • 移除之前的ref
function commitDetachRef(current: Fiber) {
  const currentRef = current.ref;
  if (currentRef !== null) {
    if (typeof currentRef === 'function') {
      // function类型ref,调用他,传参为null
      currentRef(null);
    } else {
      // 对象类型ref,current赋值为null
      currentRef.current = null;
    }
  }
}
  • 更新ref
function commitAttachRef(finishedWork: Fiber) {
  // finishedWork为含有Ref effectTag的fiber
  const ref = finishedWork.ref;
  
  // 含有ref prop,这里是作为数据结构
  if (ref !== null) {
    // 获取ref属性对应的Component实例
    const instance = finishedWork.stateNode;
    let instanceToUse;
    switch (finishedWork.tag) {
      case HostComponent:
        // 对于HostComponent,实例为对应DOM节点
        instanceToUse = getPublicInstance(instance);
        break;
      default:
        // 其他类型实例为fiber.stateNode
        instanceToUse = instance;
    }

    // 赋值ref
    if (typeof ref === 'function') {
      ref(instanceToUse);
    } else {
      ref.current = instanceToUse;
    }
  }
}
React中的ref是一个用来获取组件或DOM元素的返回值的属性。在React的生命周期函数中,你可以使用ref来强制组件重新渲染。 使用ref主要用来访问DOM元素,例如输入框、按钮等。使用ref可以实现获取输入框中的文本、获取按钮的值等操作。 ref有两种使用方式:string refs和function refs。 string refs是React较早时引入的一种使用方式,现在已经不再推荐使用。使用string refs需要给元素设置ref属性,值为字符串,然后将ref值赋值给一个成员变量。实例如下: ``` class MyComponent extends React.Component { componentDidMount() { console.log(this.inputRef.value); } render() { return( <input type="text" ref={(input) => this.inputRef = input} /> ) } } ``` function refs是现在推荐使用的一种方式,可以更好的控制和管理组件的引用。使用function refs需要将一个函数作为ref的值,这个函数会在组件挂载或卸载时被执行。实例如下: ``` class MyComponent extends React.Component { constructor(props) { super(props); this.inputRef = React.createRef(); } componentDidMount() { console.log(this.inputRef.current.value); } render() { return ( <input type="text" ref={this.inputRef} /> ) } } ``` 总结而言,ref是一个非常好用的工具,能够让开发人员更加方便的操作DOM元素,并且更好的控制和管理组件的引用。但是,需要注意的是,过度使用ref会使代码变得混乱难以维护,建议谨慎使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值