快来加入我们吧!
"小和山的菜鸟们",为前端开发者提供技术相关资讯以及系列基础文章。为更好的用户体验,请您移至我们官网小和山的菜鸟们 ( https://xhs-rookies.com/ ) 进行学习,及时获取最新文章。
"Code tailor" ,如果您对我们文章感兴趣、或是想提一些建议,微信关注 “小和山的菜鸟们” 公众号,与我们取的联系,您也可以在微信上观看我们的文章。每一个建议或是赞同都是对我们极大的鼓励!
前言
这篇文章,我们主要目的是了解一下 useRefs 的使用.
useRefs
定义
useRef
返回一个可变的 ref
对象,其 .current
属性被初始化为传入的参数(initialValue
)。返回的 ref
对象在组件的整个生命周期内保持不变。
const refContainer = useRef(initialValue)
我们都知道,React
已经提供了一个 API createRef
,它的作用同样也是创建一个 ref
,那么这个 useRefs Hook
出来的意义是什么呢?它们之间又有什么区别呢?
useRef 的特性
useRef
一个很重要的特性就是:useref
返回的 ref
对象是可变的。正如官网文档中所说,它像一个变量,像可以保存一个可变值的“盒子”。
我们已经知道的 createRef
返回的 ref
对象在每次渲染时都会返回一个新的引用,而 useRef
则返回的是相同的引用 也正如定义中所说,返回的 ref
对象在组件的整个生命周期内保持不变。这也是为什么 useRef
可以在其 .current
属性中保存一个可变值的重要原因。
可能这比较难以理解,那我们用一个例子来理解一下:
function about() {
const [count, addCount] = useState(0)
const refForUseRef = useRef()
const refForCreateRef = createRef()
if (!refForUseRef.current) {
// 如果不存在则赋值
refForUseRef.current = count
}
if (!refForCreateRef.current) {
refForCreateRef.current = count
}
return (
<>
<div>现在count的值为:{count}</div>
<div>refForUseRef的值为:{refForUseRef.current}</div>
<div>refForCreateRef的值为:{refForCreateRef.current}</div>
<button onClick={() => addCount((val) => val + 1)}>点击+1</button>
</>
)
}
看一下效果,就算组件重新渲染,由于 refForUseRef
的值一直存在,所以无法重新赋值,这就是为什么说,useRef
返回的对 ref
的引用是相同的,且在整个生命周期内保持不变。
useRef 在 Hook 中的作用
我们都知道,Hook
的出现,让我们可以在函数组件中就可以做到 Class
组件中的一些特性,我们需要注意一点,Class
组件中有一个概念叫实例变量,那么基于 Hook
的函数组件存在类似实例变量吗?
答案是肯定的,useRef Hook
不仅可以用于 DOM refs
,他还有一个重要的作用,就是容纳一个任意值的类似 Class
的实例属性,这也是前面提到的关于它的特性。
我们还是用一个例子,来感受一下使用 useRef
的函数组件的魅力吧。
用例子感受 useRef
不使用 useRef 的函数组件
function about() {
const [count, addCount] = useState(0)
function handleAlertClick() {
setTimeout(() => {
alert('弹框的count值:' + count)
}, 2000)
}
return (
<div>
<div>现在count的值为:{count}</div>
<button onClick={() => addCount((val) => val + 1)}>点击+1</button>
<button onClick={() => handleAlertClick()}>展示弹框</button>
</div>
)
}
观察这个例子的效果,我们可以发现,弹框里的 count
值是在点击展示弹框按钮时的值,并不是 count
的实时状态,这是为什么呢?
其实,当我们更新状态的时候,React
会重新渲染组件,每一次渲染都会拿到独立的 count
状态, 并重新渲染一个 handleAlertClick
函数. 每一个 handleAlertClick
里面都有它自己的 count
。 所以每次弹框展示的就是点击时的 count
值。
如何让弹框里的值实时展示 count 值呢?
这个时候就用到了我们一直在讨论的 useRef
了,直接看例子:
function about() {
const [count, addCount] = useState(0)
const refForUseRef = useRef(count)
useEffect(() => {
refForUseRef.current = count
})
function handleAlertClick() {
setTimeout(() => {
alert('弹框的count值:' + refForUseRef.current)
}, 2000)
}
return (
<div>
<div>现在count的值为:{count}</div>
<div>refForUseRef的值为:{refForUseRef.current}</div>
<button onClick={() => addCount((val) => val + 1)}>点击+1</button>
<button onClick={() => handleAlertClick()}>展示弹框</button>
</div>
)
}
因为 useRef
每次都会返回同一个引用, 所以在 useEffect
中修改的时候 ,在 alert
中也会同时被修改. 这样子, 点击的时候就可以弹出实时的 count
了.
在这个例子中,count
就类似于 Class 组件中的实例变量,useRef
让我们在函数组件中完成一些 Class
组件的功能。
总结
通过这一篇文章,我们了解到了 React Hook
为我们带了的一个钩子 useRef
,它返回的 ref
对象在组件的整个生命周期保持不变,让我们在函数组件中,也可以像 Class
组件一样保存一些实例属性,为我们开发带来了许多可能性,除了这些新奇的功能,不要忘记 ref
开始获取 DOM
属性的功能,因为在 useRef
同样可以适用。
下节预告
在下节中,我们将为大家介绍 useCallBack
,敬请期待!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。