React源码解析第三节

ref的三种使用方式与forwardRef

ref的功能
场景:有一个class类组件,通过ref获取子组件实例或者DOM节点,进行手动操作,而不仅仅是props更新来更新节点。
获取节点自己做一些绑定或其他操作。
(当然除此之外可以querySelect,document.querySelector("#demo");
querySelector() 方法返回文档中匹配指定 CSS 选择器的一个元素。)

一、ref的三种使用方式

  • 源码前言

function Component (props, context,updater)
Component.prototype.setState = function(partialState,callback) {

this.updater.enqueueSetState(this,partialState,callback,)
}

updater.enqueueSetState是在reactDOM里实现的。
Component 核心是一样的,
更新的流程不同
类的继承中初始化定义函数的时候,在他的原型上还可以使用传递进来的参数吗?源码上是可以的,回家试一试。

  • React中ref的三种使用方式:
应用:
1.this.refs.stringRef.textContent = "string ref got"
2.this.methodRef.textContent = "method ref got"
3.//先创建一个ref对象
export default class Comp extends React.Component {
 super();
 this.objRef = React.createRef();
}
//
this.objRef.current.textContent = "obj ref got"

<p ref = {this.objRef}>asdf</p>
//string ref    想要获取的那个节点的props上面使用ref属性传入一个字符串,
react在完成这个节点的渲染之后,会在this.ref上面挂载string对应的key
也就是stringRef(如果是DOM节点就会对应DOM的实例,如果是子组件就对应组件的实例classComponent)
>但是如果是function Component呢,正常来说是会失败的,因为function Component是
>没有实例的,那怎么解决呢,后面的forward-ref(让我们在function Component使用ref也不会出错)
<p ref = "string"> asdf</p>   下一个大版本(React17)会废弃 ,ref会传入一个字符串,然后
//function    参数ele是节点对应的实例,DOM节点的实例,或者组件的实例
<p ref = {ele => (this.methodRef = ele) }></p>
//React提供给我们的一个API:首先在class	Component中使用
this.objRef = React.createRef() 创建一个对象相当于//{current:null }
<p ref = {this.objRef}>asdf</p>
//然后把创建的对象(通过ref={}形式)传给某一个节点,就会把某个对象
的实例挂载到,current这个属性上面。

二、forwardRef

假设:当时纯函数组件的时候,没有实例对象,就不能使用获得对应的实例对象,follow me 
import React, { Component } from 'react'
cosnt TargetComponent = (props,ref) => {
  return  <input type = "text"  ref = {ref}/>
}
export default class Comp extends Component {
    constructor() {
      super();
      this.ref = React.createRef();
      //创建一个对象   { current : null }
    }
    componentDidMount() {
      this.ref.current.value = "ref get input"
    }
    render() {
      return  <TargetComponent ref = {this.ref} />
    }
}

那有同学就问:我自己定义的组件,我知道他是不是纯函数式组件,所以我会做一个判断用不用ref,
所以就不存在使用forwardRef来解决这个问题。

反驳:
1.如果我是一个组件的提供者,我开发了开源的组件,那我export之后,使用者不清楚这个是否是
纯函数组件(有没有实例)。
2.还有就是我们使用redux这种包,他会给我们提供一个方法connect,connect这个方法里面用到一个高阶
属性hoc(high order component),也就是通过调用connect传入我们自己定义的组件之后,返回的是包装
了这个组件的另外一个组件。如果我们直接传ref,这个ref对应的是被包装之后的组件,所以通过forward
实现了ref的传递(因为正常情况下我们是不能够通过下一层组件拿到ref这个属性的,因为他不属于props
里面)。

解决方案:

import React from 'react'
const TargetComponent = React.forwardRef((props,ref) => (
  <input type = "text" ref = {ref} />
))

export default class Comp extends React.Component {
  constructor(){
  super();
  this.ref = React.createRef();
   }
  
  componentDidMount() {
  this.ref.current.value = "ref get input"
   }
  
  render() {
     return <TargetComponent ref = {this.ref} />
     //使用ref将节点或者组件实例传入this.ref这个对象{current:null}
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值