总结ref的⽤法
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 />
typeof的用法console.log(this.webview)
通过ateRef()创建ref:
this.webview = ateRef();
// 引⽤
<WebView ref={this.webview} />
// 获取当前节点
console.warn(this.webview.current)
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,f !== null,即组件⾸次render时存在ref属性
对于update,f !== f,即组件更新时ref属性改变
commit阶段:
为包含Ref effectTag的fiber执⾏对应操作
移除之前的ref
function commitDetachRef(current: Fiber) {
const currentRef = f;
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 = f;
// 含有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;
}
}
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论