一、useRef的缓存作用,在多次渲染之间共享数据-停止定时器
错误用法:每次setCount,refTimeId都会重新声明为null,导致点击按钮时timeId为null,关闭定时器失败
import React, { useEffect, useState,useRef } from 'react'
const F:React.FC=()=> {
const [count, setCount] = useState(0)
const refTimeId = null
console.log(refTimeId) //null
useEffect(() => {
refTimeId= setInterval(() => {
setCount((count) => count + 1)
}, 1000)
}, [])
const hClick = () => {
console.log(refTimeId) // null
clearInterval(refTimeId)
}
return (
<div>
count:{count}
<button onClick={hClick}>点击停止定时器</button>
</div>
)
}
export default F
正确用法:useRef具有缓存作用,用useRef定义refTimeId,useRef只会声明一次,它的作用是提供一个可以在函数式组件中访问的全局变量,而不必渲染组件
import React, { useEffect, useState,useRef } from 'react'
const F:React.FC=()=> {
const [count, setCount] = useState(0)
const refTimeId = useRef<NodeJS.Timer>()
console.log(refTimeId.current)
useEffect(() => {
refTimeId.current= setInterval(() => {
setCount((count) => count + 1)
}, 1000)
console.log(refTimeId.current) // 1
}, [])
const hClick = () => {
console.log(refTimeId.current) // 1
clearInterval(refTimeId.current)
}
return (
<div>
count:{count}
<button onClick={hClick}>点击停止定时器</button>
</div>
)
}
export default F
二、使用useRef获取DOM元素
import React, { useRef } from 'react'
import reactDom from 'react-dom'
F:React.FC=()=>{
const inputEl = useRef(null)
const hClick = () => {
inputEl.current.focus() // 这里的inputEl.current就是input元素,所以可以调用原生input的方法
}
return (
<div>
<input type="text" ref={inputEl} />
<br />
<button onClick={hClick}>表单获取焦点</button>
</div>
)
}
export F
useState与useRef的区别
const [isVisible, setIsVisible] = useState(false),这里有一点值得注意:调用setIsVisible函数会使isVisible变量更新,但是这个状态如果你立马用consol.log去打印是得不到最新值的。需要使用useEffect的第二个参数来监听我们需要变化的值,以获取变化后的最新值。或者说组件重新渲染后,我们就能看到最新值了。
useState触发重新渲染,useRef不触发
useState异步更新其值,useRef同步更新
变量是决定视图图层渲染的变量,请使用useState,其他用途useRef