一. 介绍useRef
- 先看下官方文档对useRef的描述
- 传送门:useRef hook
二 . 使用useRef
- 如上面官方文档示例所示,在实际代码运用中还有很多使用方式,我们在写后台管理系统时,经常会用到表格查询。我们看下面一段代码,如何用useRef来优化表格查询
import React, { useCallback, useRef } from 'react'
import { debounce } from 'lodash'
const refDemo:React.FC = () => {
const searchRef = useRef()
searchRef.current = searchFn
const debounceSearch = useCallback(
debounce(() => searchRef.current(), 200), []
)
const searchFn = () => {
console.log('开始查询')
}
return (
<>
<button onClick={debounceSearch} >查询</button>
</>
)
}
使用useRef后,会挂载一个.current属性,将查询的方法赋值给searchRef.current。点击调用searchRef.current方法触发查询,为什么要用useRef来触发查询而不是直接触发查询呢,因为变更 .current 属性不会引发组件重新渲染。这对于性能优化有一定好处
- 使用useRef在父组件中触发子组件方法。在父组件中使用useRef并传递给子组件,子组件通过useImperativeHandle钩子将ref进行绑定。这样就可以在父组件中操作子组件方法。useImperativeHandle一般和forwardRef共同使用。附上useImperativeHandle官方文档,传送门useImperativeHandle hook
const childComponent = React.forwardRef((props, ref) => {
const [visible, setVisible] = useState(false)
const [text,setText] = useState('显示')
useImperativeHandle(ref, () => ({
showModal: () => { setVisible(true) },
changeText: () => {
setVisible(true)
setText('改变文案') }
}))
return (
<div>
<Modal visible={visible} title='ref' >{text}</Modal>
</div>
)
})
const UseRef: React.FC = (props,ref) => {
const modalRef = useRef(null)
const clickFun = (value:'showmodal' | 'changetext') => {
if(value==='showmodal') {
modalRef?.current?.showModal()
} else {
modalRef?.current?.changeText()
}
}
return (
<div>
<Button onClick={()=>clickFun('showmodal')} >点击显示弹框</Button>
<Button onClick={()=>clickFun('changetext')} >点击显示弹框并改变文案</Button>
<childComponent ref={modalRef} />
</div>
)
}
在父组件中点击按钮通过useRef触发子组件更新