关于前端:hooks-系列四useRefs

39次阅读

共计 2717 个字符,预计需要花费 7 分钟才能阅读完成。

快来退出咱们吧!

“ 小和山的菜鸟们 ”,为前端开发者提供技术相干资讯以及系列根底文章。为更好的用户体验,请您移至咱们官网小和山的菜鸟们 (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,敬请期待!

正文完
 0