简介
useRef
总共有三种用法:
1. 作用于Dom元素
2. 获取子组件的实例(只有类组件可用)
3. 在函数组件中的一个全局变量,不会因为重复 render 重复申明, 类似于类组件的 this.xxx
什么是useRef
useRef
返回一个可变的 ref 对象,其 .current
属性被初始化为传入的参数(initialValue
)。返回的 ref 对象在组件的整个生命周期内保持不变。
特性
useRef
返回一个可变的ref
对象,该对象只有个current
属性,初始值为传入的参数(initialValue
)。- 返回的
ref
对象在组件的整个生命周期内保持不变,每次返回同一个引用 - 当更新
current
值时并不会引起页面重新渲染 - 更新
useRef
是side effect
(副作用),所以一般写在useEffect 或 event
里 - useRef 类似于类组件的 this
使用方式/语法
const refContainer = useRef(initialValue);
举一个栗子
Parent.js
function TextInputWithFocusButton() {
const inputEl = useRef(null);
const onButtonClick = () => {
// `current` 指向已挂载到 DOM 上的文本输入元素\
inputEl.current.focus();
};
return (
<View>
<Input ref={inputEl} type="text" />
<Button onClick={onButtonClick}>Focus thenput</Button>
</View>
);
}
本质上,useRef
就像是可以在其 .current
属性中保存一个可变值的“盒子”。
你应该熟悉 ref 这一种[访问 DOM] 的主要方式。如果你将 ref 对象以 <View ref={myRef} />
Taro 都会将 ref 对象的 .current
属性设置为相应的 DOM 节点。
然而,useRef()
比 ref
属性更有用。它可以[很方便地保存任何可变值],其类似于在 class 中使用实例字段的方式。
这是因为它创建的是一个普通 JavaScript 对象。而 useRef()
和自建一个 {current: ...}
对象的唯一区别是,useRef
会在每次渲染时返回同一个 ref 对象。
注意
当 ref 对象内容发生变化时,useRef
并不会通知你。变更 .current
属性不会引发组件重新渲染。如果想要在 Taro 绑定或解绑 DOM 节点的 ref 时运行某些代码,则需要使用[回调 ref]来实现。
再举第二个栗子
获取子组件的实例(只有类组件可用)
class Children extends PureComponent{
render() {
const {count} = this.props
return (
<div>{count}</div>
)
}
}
function App() {
const [count,setCount] = React.useState(0)
const childrenRef = React.useRef(null)
const clickMeHandle = React.useMemo(()=>setCount((count)=> count + 1),[])
return (
点击了-{count}-次
<Children ref={childrenRef} count={count}/>
<button onClick={clickMeHandle}>点击</button>
)
}
再举第三个栗子
在函数组件中的一个全局变量,不会因为重复 render 重复申明, 类似于类组件的 this.xxx
获取子组件的实例(只有类组件可用)
function Preson() {
const timer = React.useRef(null)
const clickHandle = () => {
timer.current = setTimeout(()=>{
console.log(timer)
},1000)
}
const clearHandle = () => clearTimeout(timer.current)
return (
<>
<button onClick={clickHandle}>开始</button>
<button onClick={clearHandle}>清楚</button>
</>
)
}