为何不推荐在react组件中直接定义变量?探秘useRef的使用以及userRef与useState的区别
为何不推荐在react组件中直接定义变量?探秘useRef的使用以及userRef与useState的区别
前言
今天在写代码的时候遇到一个问题,我的一个组件需要维护一个不需要在页面中渲染的变量。那么我想,既然它不需要渲染,我直接用let
变量新建一个不就可以了吗?
但是当我真正用这个let
创建的变量时,才意识到大事不好,原来这么使用变量有一个大问题!
为什么要有hook
要说明问题是什么,我们需要先弄明白一件事情,我们使用函数式组件时我们怎么去render
?在我们使用类式组件时,rerender
可能是简单的调用一次render
方法,那对于函数式组件呢?函数式组件的render
写在return
语句中,很明显我们需要重新执行整个函数。
那么我在前言部分提到的问题就呼之欲出了:组件每次渲染更新都会使得变量变为初始值。也就是说我在组件的一个函数中修改变量并更新组件,想在另一个函数中使用时我们获取到的就只会是初始值了。
可以看到,函数式组件是没有状态的!而react引入hook
的原因就是补全函数式组件在这方面的缺陷。比如useState,当函数重新渲染时,state能够从状态池中获取到上次render的状态,像useEffect能根据变量来确定是否需要渲染,从而起到生命周期函数的作用。
也就是说,如果我们希望有一个能在每次渲染的时候不被重新初始化的变量,那么我们就需要借助hook了。
那么问题又来了,我们应该用哪一个hook
呢?这里我推荐一个:useRef
。
useRef
我们使用useRef()
创建的变量不会每次都被重新渲染
1 |
|
useRef
的特性如下:
ref的值通过
current
属性获取ref是可以更改的
更改ref的值不会引起
rerender
如果ref的值被用于渲染,那么则不可更改
不建议在组件渲染中读写ref的
current
,推荐在useEffect
与event handler
中使用使用ref.current
可以看到,ref就是为我们保存不用每次初始化而且不必渲染的变量而生的。
useRef与useState
那么为什么我们要用ref而不去使用state呢?这两个hook有两个非常大的区别:
ref不会引起rerender,而state会。当我们调用setState时,会触发rerender,而在使用ref就不必担心这个,你可以随意的使用
ref是同步的,state是异步的。当我们同步的使用useState更新数据之后,我们会获取不到最新的值,因为他是异步更新的。而ref则不会有这样的问题,你可以在更新之后立刻获取到最新的值。
所以对我现在的需求来说,useRef
要比useState
合适的多。
使用useRef操作dom
useRef的另一个重要的作用就是操作dom,我们在这边也顺带提一下吧。
我们可以这样使用ref:
1 |
|
我们通过jsx中的VNODE
的ref属性属性传递我们的ref,这样react会在渲染的时候自动将current
的值设置为node。然后我们就可以访问到这个node了。
当这个node被从页面中移除时,ref.current
也会被设置为null
总结
如果你希望在react函数式组件中保存一个不会每次渲染时更新并且无须被渲染的值,那么useRef
是你的不二之选