React 學習筆記 — useImperativeHandle 怎麼用?
useImperativeHandle 是什麼?
useImperativeHandle
is a React Hook that lets you customize the handle exposed as a ref.
useImperativeHandle
這個 hook 主要的功能,是讓子元件可以決定要 expose 給父元件的任何屬性,透過 ref,父元件就可以直接操作子元間內的屬性或是方法。
useImperativeHandle
是透過 ref 來將內部的屬性或是功能 expose 出去,所以使用上要搭配 forwardRef、useRef 來一起使用。
關於 React 的 ref 相關複習,可以參考:
使用情境
自己實務上用到的機會並不是太多,主要情境會是,當一個獨立的元件,內部的控制、或是屬性,需要被外部元件操控的時候,或是當想控制子元件內的狀態,又不想把這些狀態往外層抽的時候,這時候就可以考慮來使用這個useImperativeHandle
hook 了。
比如說,某個在其他元件完成的 API call,成功之後需要對於這個特定元件內部的 state 做 reset,這時候就可以把 reset 的內部 function expose 出去給外面使用。
使用範例
下面這個例子的 Form 是一個獨立的元件,他紀錄了一個 name 的狀態,與一個可以 reset name 的 function。這時候我們將他的 reset 功能透過 useImperativeHandle
expose 出去,讓外層的元件來使用。
子原件 Form
import React, { useState, useImperativeHandle, forwardRef } from 'react'
const Form = forwardRef((props, ref) => {
const [name, setName] = useState('');
// 定義一個 reset function
const reset = () => {
setName('');
}
// 使用 useImperativeHandle 來決定要向外 expose 的屬性與方法
useImperativeHandle(ref, () => {
return {
reset
};
}, []);
return (
<>
Form Component
<div>
Name:
<input
value={name}
onChange={(e) => setName(e.target.value)}
/>
</div>
<button onClick={reset}>Form reset</button>
</>
)
});
export default App
外層父元件
import React, { useRef } from 'react'
const App = () => {
// 定義一個 ref
const formRef = useRef(null);
return (
<>
<div>Parent Component</div>
<button onClick={() => {
// 透過 formRef.current 來拿到子元件 expose 出來的 reset function
formRef.current.reset();
}}>
Parent control reset
</button>
<hr/>
<Form ref={formRef} />
</>
)
};
實際的畫面可以看這裡,這樣就可以使得父層的元件也可以操作 reset 的功能,來把 Form 的內容重置了。
如果你覺得這篇文章對你有幫助,歡迎買杯咖啡贊助 ☕️ 謝謝