开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 15天,点击查看活动详情
useRef是什么
它是react的一个hooks,用来做一些state不太方便做的事,同时也可以用来获取到dom对象.
那么它有什么特点呢?
- useRef对象返回一个可变的ref对象,同时只有一个current属性,可以传入一个初始值.
- 可变的ref对象在整个生命周期中是保持不变的,不像state那样会导致组件的重复渲染,而 useState 更新值时会触发页面渲染.
- 更新 useRef 是 side effect (副作用),所以一般写在 useEffect 或 event handler 里.
useRef主要用途
可以用来实时保存上一次的值
要知道useState是异步更新的,不能同步获取到值,只能在useEffect中获取到更新后的值,但是useRef可以拿到最新的值,且不会触发组件的重新渲染.
function usePrevious(value) {
const ref = useRef();
useEffect(() => {
ref.current = value;
});
return ref.current;
}
做一个定时器
即使useState发生变化导致组件重新渲染,ref的值也还是上次的值.所以我们可以用来在组件中保存一些不需要经常变化的值,因此我们可以来做一个定时器.
const App = () => {
let timer;
useEffect(() => {
timer = setInterval(() => {
console.log('触发了');
}, 1000);
},[]);
const clearTimer = () => {
clearInterval(timer);
}
return (
<>
<Button onClick={clearTimer}>停止</Button>
</>)
}
获取子组件的属性和方法
import React, {MutableRefObject, useState, useEffect, useRef, useCallback} from 'react'
interface IProps {
//prettier-ignore
label: string,
cRef: MutableRefObject<any>
}
const ChildInput: React.FC<IProps> = (props) => {
const { label, cRef } = props
const [value, setValue] = useState('')
const handleChange = (e: any) => {
const value = e.target.value
setValue(value)
}
const getValue = useCallback(() => {
return value
}, [value])
useEffect(() => {
if (cRef && cRef.current) {
cRef.current.getValue = getValue
}
}, [getValue])
return (
<div>
<span>{label}:</span>
<input type="text" value={value} onChange={handleChange} />
</div>
)
}
const ParentCom: React.FC = (props: any) => {
const childRef: MutableRefObject<any> = useRef({})
const handleFocus = () => {
const node = childRef.current
alert(node.getValue())
}
return (
<div>
<ChildInput label={'名称'} cRef={childRef} />
<button onClick={handleFocus}>focus</button>
</div>
)
}
export default ParentCom
像这样我们便可以去获取到子组件的属性和方法.
结尾
- 不同组件之间和同一个组件被多次使用,ref也是不同的.
- 组件重新渲染之后,全局变量会被重新创建,ref 则不会被刷新。