createRef和useRef区别——useRef的使用——forwardRef完成类组件的绑定—— useImperativeHandle——映射ref对象——更新同步
Posted 勇敢*牛牛
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了createRef和useRef区别——useRef的使用——forwardRef完成类组件的绑定—— useImperativeHandle——映射ref对象——更新同步相关的知识,希望对你有一定的参考价值。
useRef简单的使用
const usernameUseRef = useRef()
<input type="text" ref=usernameRef />
<button
onClick=() =>
console.log(usernameRef.current.value)
>
createRef和useRef区别
- createRef 它可以用在类组件和函数组件中,声明式不能给初始值
const usernameCreateRef = createRef()
- useRef 它只能使用在函数组件中,useRef它可以在声明时给初始值,但一般为null
const usernameUseRef = useRef(null)
- createRef每次重新渲染时都会创建一个ref对象,组件被重新渲染时它也会重新创建,但是因为类组件中它有生命周期,我可以在构造函数中创建这个ref,也就会执行一次。
- useRef第1次渲染时创建一个对象之后,再新渲染时,如果发现这个对象已经存在过不会再创建,它的性能更好一些,在函数组件中推荐使用useRef
测试:验证;
import React, createRef, useRef, useEffect, useState from 'react';
const App = () =>
const usernameCreateRef = createRef();
const usernameuseRef = useRef();
const [value, setvalue] = useState(100)
if (!usernameCreateRef.current)
usernameCreateRef.current = value;
if (!usernameuseRef.current)
usernameuseRef.current = value;
return (
<div>
<hr />
<h1>
createRef:usernameCreateRef.current
</h1>
<h1>
useRef:usernameuseRef.current
</h1>
<hr />
<h1>
</h1>
<button onClick=
() =>
setvalue(v => v + 1)
>++++</button>
</div>
);
export default App;
forwardRef完成类组件的绑定
- 如果ref对象绑定在自定义类组件中,则得到当前自定义类组件的实例,从而可以实现组件通信
- 如果ref直接绑定在自定义函数组件中,则不行,因为函数组件没有实例,所以会报错
- 函数组件如果你需要绑定ref,则需要通过它提供的一个顶层api方法来增强函数组件从而实现函数组件也可以绑定ref对象
React.forwardRef
- 直接使用ref的话就会报错
通过这个forwardRef
来包裹一下这个子组件就行。
就可以ref了,具体还得往下看。
import React, useRef,forwardRef from 'react';
const Child = forwardRef((props,_ref) =>
return (
<div>
<h1 ref=_ref>子组件</h1>
</div>
);
)
const App = () =>
const ref = useRef();
return (
<div>
<Child ref=ref/>
<button onClick=e=>
console.log(ref.current);
>@@@@@</button>
</div>
);
export default App;
当然通过这个useref可以初始化的特性,ref也可以完成对组件的传值。
const ref = useRef(100);
const App = () =>
const ref = useRef(100);
return (
<div>
<Child ref=ref/>
<button onClick=e=>
ref.current++
console.log(ref.current);
>@@@@@</button>
</div>
);
export default App;
useImperativeHandle映射对象
useImperativeHandle 集合useRef和forwardRef 方法来模拟给函数组件绑定ref对象来得到子组件中对外暴露出来的方法或数据
useImperativeHandle(_ref,()=>
return
value,
changevalue,
childref
)
- 参数1:就是父组件传过来的ref对象
- 参数2:回调函数,返回一个对象,穿透给父组件的数据
import React, useRef,forwardRef, useState ,useImperativeHandle from 'react';
const Child = forwardRef((props,_ref) =>
let [value,setValue] = useState();
const changevalue = (newvalue)=>
setValue(newvalue)
const childref = useRef()
useImperativeHandle(_ref,()=>
return
value,
changevalue,
childref
)
return (
<div>
<h1>子组件</h1>
<input type="text" name="" id="" ref=childref value="123s"/>
<h2>value</h2>
</div>
);
)
const App = () =>
const ref = useRef(100);
return (
<div>
<Child ref=ref/>
<hr />
<button onClick=e=>
// 获取到返回来的映射对象,操作子组件的内容
console.log(ref.current);
ref.current.changevalue("niupeng")
>@@@@@</button>
</div>
);
export default App;
useLayouEffect同步
import React, useLayoutEffect, useEffect from 'react'
const App = () =>
// js事件循环中,同步优先于异步
// 异步
useEffect(()=>
console.log('useEffect');
,[])
// 同步 如果你是操作dom来说,建议用它
useLayoutEffect(()=>
console.log('useLayoutEffect');
document.title = '你好react'
,[])
return <div>
<h3>App组件</h3>
</div>
export default App
以上是关于createRef和useRef区别——useRef的使用——forwardRef完成类组件的绑定—— useImperativeHandle——映射ref对象——更新同步的主要内容,如果未能解决你的问题,请参考以下文章
React.JS Ref 中的 Ref 错误 - createRef、useRef 和 using Refs