在 React hooks 中 useImperativeHandle 是一个相对较少使用的 hook,且使用它的时候也必须搭配着 React.forwardRef 来使用。如果是刚开始学 React 或是从来都没有仔细看手册的人,可能都不会知道有这个 hook 的存在,或是早就忘记它的存在。今天就让我来了解了解 useImperativeHandle,这个冷门又容易被遗忘的 hook 吧!或许了解之後,可能在某些情境下可以考虑使用它。
在开始介绍 useImperativeHandle 之前,先来介绍它的好搭档 forwardRef。forwardRef 与 memo 一样是个 HOC (High order component) ,接受一个元件并回传一个元件。
那为什麽需要 forwardRef 呢?直接来看下面的范例:
function App() {
const inputRef = React.useRef()
return (
<div>
<input type="text" ref={inputRef} />
</div>
)
}
ReactDOM.render(<App />, document.getElementById('root'))
在这个范例中,我们使用了 useRef 并在 input ref 属性挂上,以取得 input 的 DOM node。
那假设今天有种情况是需要将 input 抽象化成一个元件,并尝试将 ref 透过 props 传递下去,挂在 input 的 ref 上,如下
function InputField({ ref }) {
return (
<input type="text" ref={ref} />
)
}
function App() {
const inputRef = React.useRef()
return (
<div>
<InputField ref={inputRef} />
</div>
)
}
ReactDOM.render(<App />, document.getElementById('root'))
这个时候打开 console 就会发现 React 丢出的错误讯息
在 function component 中是不能够将 ref 作为 props 传递的,这个时候 forwardRef 就登场啦!我们可以用 forwardRef 将元件包起来,他就会回传一个可以传递 ref 的元件给我们。
const InputField = React.forwardRef((props, ref) => {
return (
<input type="text" ref={ref} />
)
})
改成这样子之後,我们就能够顺利取的 input DOM node 了!
介绍完 forwardRef 的基本使用方式之後,我们再来看看 useImperativeHandle 在 React 官方的说明以及基本的用法
useImperativeHandle customizes the instance value that is exposed to parent components when using ref
useImperativeHandle(ref, createHandle, [deps]))
简单来说,我们可以将子元件定义的变数或是函式,透过 useImperativeHandle 给父层传下来的 ref 定义属性。让我们直接看看使用范例:
const InputField = React.forwardRef((props, ref) => {
const inputRef = React.useRef()
React.useImperativeHandle(
ref,
() => {
return {
focus: () => {
inputRef.current.focus()
}
}
})
return (
<input type="text" ref={inputRef} />
)
})
function App() {
const InputFieldRef = React.useRef()
function clickHandler() {
InputFieldRef.current.focus()
}
return (
<div>
<button onClick={clickHandler}>focus</button>
<InputField ref={InputFieldRef} />
</div>
)
}
ReactDOM.render(<App />, document.getElementById('root'))
在范例中,useImperativeHandle 第一个参数接收来自父层定义的 ref,然後我们在第二个 callback 参数必须回传一个物件,而这个物件就会成为父层 ref 中 current 属性的值。所以我们就在这个物件中定义了 focus 属性,让父层 ref 可以呼叫这个方法。
以上就是今天的分享,如果有任何问题都欢迎在下方留言!
该文章同步发布於:我的部落格
>>: [28] 用 python 刷 Leetcode: 1013
上一篇介绍了Palindromes,上一题讲解了如何辨别是不是镜像字或是回文字的题目,只要先辨别出镜...
主要呈现实作成果 以下内容有参考教学影片,底下有附网址。 (内容包括我的不专业解说分析及在实作过程中...
上两期说到VR和AR,这期来介绍介於他们两个之间的MR。 MR(混合实境):MR是一种介於VR(虚拟...
当花了很多时间整理经营作品集後,得到主动来信询问真的会非常感动,可以感受到自己是被社会所需要的,在肯...
哈罗,大家好,欢迎跟着温秘书继续 Microsoft 365 开发人员计画。 在昨天完成基础设定後,...