useRef的主要作用
操纵dom元素
- uesRef返回的对象,可以作为ref的值传递给即将要操作的子组件,然后子组件内部通过useImperativeHandle暴露句柄,父组件通过useValue.current.xxx来调用子组件方法即可。
- 注意:ref只能传递到子组件上,无法传递给子组件内部组件,例如子组件的input组件,这时就需要forwardRef
import { useRef } from 'react';
const refValue = useRef(initialValue)
refValue.current
持久化数据
import React, { useLayoutEffect, useRef, useState } from 'react';
function App() {
let num = 0
let [count, setCount] = useState(0)
const handleClick = () => {
setCount(count + 1)
num = count;
};
return (
<div>
<button onClick={handleClick}>增加</button>
<div>{count}:{num}</div>
</div>
);
}
export default App;
- 首先,setState是异步的,num一直被赋予旧值。
- 其次,持久化的只有state,即使num被赋予的不是旧值,那每次更新state,组件重新render,也会不断地初始化num。
- 所以出现了useRef来持久化数据
import React, { useLayoutEffect, useRef, useState } from 'react';
function App() {
let num = useRef(0)
let [count, setCount] = useState(0)
const handleClick = () => {
setCount(count + 1)
num.current = count + 1;
};
return (
<div>
<button onClick={handleClick}>增加</button>
<div>{count}:{num.current}</div>
</div>
);
}
export default App;
- 这种解决办法 既不会导致num是state的旧值 也避免了num无法持久化。
- 关于旧状态的问题,其实也可以不count + 1,可以把num.current = count放到useEffect里,依赖数组为state。