[React] 核心属性refs—— 需要注意的问题

官网链接:Refs and the DOM – React

1. 避免使用字符串的ref

什么是字符串的ref ?

<button ref="test"></button>

ref所赋予的值是一个字符串

官方不推荐使用,以下为官方原话

过时 API:String 类型的 Refs

如果你之前使用过 React,你可能了解过之前的 API 中的 string 类型的 ref 属性,例如 "textInput"。你可以通过 this.refs.textInput 来访问 DOM 节点。我们不建议使用它,因为 string 类型的 refs 存在 一些问题。它已过时并可能会在未来的版本被移除。

其主要的原因在Update nuances of ref callback calling by unel · Pull Request #8333 · facebook/react · GitHub也大致说了以下

There are multiple problems with it:

  • It requires that React keeps track of currently rendering component (since it can't guess this). This makes React a bit slower.
  • It doesn't work as most people would expect with the "render callback" pattern (e.g. <DataGrid renderRow={this.renderRow} />) because the ref would get placed on DataGrid for the above reason.
  • It is not composable, i.e. if a library puts a ref on the passed child, the user can't put another ref on it (e.g. #8734). Callback refs are perfectly composable.

总体最主要的原因就是效率不高,同时当组件的层次复杂时,可能会存在其他问题

来至知乎评论区的回答:
1、当 ref 定义为string 时,需要 React 追踪当前正在渲染的组件,在 reconciliation 阶段, React Element 创建和更新的过程中, ref 会被包装为一个闭包函数, 等待 commit 阶段被执行,这会对React 的性能产生一些影响.
2、当使用 render callback 模式的时候,使用 string ref 会造成 ref 挂载位置产生歧义。

3、string ref 无法被组合,例如一个第三方库的父组件已经给子组件传递了 ref,那么我们就无法再在子组件上添加 ref 了,而 callback ref 可完美解决此问题。

2.回调中的refs

官方说明

关于回调 refs 的说明

如果 ref 回调函数是以内联函数的方式定义的,在更新过程中它会被执行两次,第一次传入参数 null,然后第二次会传入参数 DOM 元素。这是因为在每次渲染时会创建一个新的函数实例,所以 React 清空旧的 ref 并且设置新的。通过将 ref 的回调函数定义成 class 的绑定函数的方式可以避免上述问题,但是大多数情况下它是无关紧要的。

也就是说,我们的ref第一次其实就是初始化,第二次才会真正的传值,正常情况下其实并没有什么影响,因为最终都会得到值,但是在某些特殊情况这种会导致,比如foucus一个button,第一次很容易得到一个null,在console中是可以发现日志的。(这个案例正常不会发生,还是得基于业务的复杂程度)用mount写单元测试的时候更加明显,因为第一次渲染你的得不到ref的路径的。导致值无法获取判断。

同时官方推荐使用class进行操作。但是class是可以解决初始值为null的问题,但是他为一个实例,等于一个默认值。在有些需要灵活性大点的业务还是会存在问题的,这种业务大多数都是focus相关的问题。

3. refs的渲染问题

当之间使用以下这种格式的时候

<button ref = this.but></button>

正常的系统运行是没有问题的,但是这不能够进行单元测试的full render,当你去渲染的时候,会报出 ref需要是一个类或者是一个string的形式。具体还没有解决办法,只能使用shallow render进行操作,但是这个单元测试不能实现互动的效果,只能简单的得出该组件相关的属性值

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值