useImperativeHandle הוא React Hook שמאפשר להתאים אישית את ה-handle שנחשף כ-ref.
useImperativeHandle(ref, createHandle, dependencies?)Reference
useImperativeHandle(ref, createHandle, dependencies?)
קראו ל-useImperativeHandle ברמה העליונה של הקומפוננטה כדי להתאים אישית את ref handle שהיא חושפת:
import { forwardRef, useImperativeHandle } from 'react';
const MyInput = forwardRef(function MyInput(props, ref) {
useImperativeHandle(ref, () => {
return {
// ... your methods ...
};
}, []);
// ...Parameters
-
ref: ה-refשקיבלתם כארגומנט השני מתוךforwardRefrender function. -
createHandle: פונקציה שלא מקבלת ארגומנטים ומחזירה את ref handle שתרצו לחשוף. ה-handle הזה יכול להיות מכל סוג. בדרך כלל תחזירו אובייקט עם המתודות שתרצו לחשוף. -
אופציונלי
dependencies: רשימה של כל הערכים הריאקטיביים שמופנים בתוך קוד ה-createHandle. ערכים ריאקטיביים כוללים props, state וכל המשתנים והפונקציות שמוגדרים ישירות בתוך גוף הקומפוננטה. אם ה-linter שלכם מוגדר ל-React, הוא יוודא שכל ערך ריאקטיבי מצוין נכון כ-dependency. רשימת ה-dependencies חייבת להיות במספר פריטים קבוע ולהיכתב inline כמו[dep1, dep2, dep3]. React תשווה כל dependency לערך הקודם שלו באמצעותObject.is. אם re-render גרם לשינוי ב-dependency כלשהו, או אם השמטתם את הארגומנט הזה, פונקצייתcreateHandleתרוץ מחדש, וה-handle החדש שייווצר יוקצה ל-ref.
Returns
useImperativeHandle מחזיר undefined.
שימוש
חשיפת ref handle מותאם לקומפוננטת ההורה
כברירת מחדל, קומפוננטות לא חושפות את ה-DOM nodes שלהן לקומפוננטות הורה. למשל, אם אתם רוצים שלקומפוננטת ההורה של MyInput תהיה גישה ל-<input> DOM node, צריך לבצע opt-in עם forwardRef:
import { forwardRef } from 'react';
const MyInput = forwardRef(function MyInput(props, ref) {
return <input {...props} ref={ref} />;
});עם הקוד למעלה, ref ל-MyInput יקבל את <input> DOM node. אבל אפשר גם לחשוף ערך מותאם אישית במקום. כדי להתאים את ה-handle שנחשף, קראו ל-useImperativeHandle ברמה העליונה של הקומפוננטה:
import { forwardRef, useImperativeHandle } from 'react';
const MyInput = forwardRef(function MyInput(props, ref) {
useImperativeHandle(ref, () => {
return {
// ... your methods ...
};
}, []);
return <input {...props} />;
});שימו לב שבקוד למעלה, ה-ref כבר לא מועבר ל-<input>.
לדוגמה, נניח שאתם לא רוצים לחשוף את כל <input> DOM node, אלא רק שתי מתודות: focus ו-scrollIntoView. כדי לעשות זאת, שמרו את ה-DOM האמיתי של הדפדפן ב-ref נפרד. אחר כך השתמשו ב-useImperativeHandle כדי לחשוף handle שמכיל רק את המתודות שאתם רוצים שההורה יוכל לקרוא להן:
import { forwardRef, useRef, useImperativeHandle } from 'react';
const MyInput = forwardRef(function MyInput(props, ref) {
const inputRef = useRef(null);
useImperativeHandle(ref, () => {
return {
focus() {
inputRef.current.focus();
},
scrollIntoView() {
inputRef.current.scrollIntoView();
},
};
}, []);
return <input {...props} ref={inputRef} />;
});עכשיו, אם קומפוננטת ההורה מקבלת ref ל-MyInput, היא תוכל לקרוא למתודות focus ו-scrollIntoView. עם זאת, לא תהיה לה גישה מלאה ל-<input> DOM node עצמו.
import { useRef } from 'react'; import MyInput from './MyInput.js'; export default function Form() { const ref = useRef(null); function handleClick() { ref.current.focus(); // This won't work because the DOM node isn't exposed: // ref.current.style.opacity = 0.5; } return ( <form> <MyInput placeholder="Enter your name" ref={ref} /> <button type="button" onClick={handleClick}> Edit </button> </form> ); }
חשיפת מתודות imperative משלכם
המתודות שאתם חושפים דרך imperative handle לא חייבות להתאים בדיוק למתודות DOM. לדוגמה, קומפוננטת Post הזו חושפת מתודה בשם scrollAndFocusAddComment דרך imperative handle. זה מאפשר ל-Page ההורה לגלול את רשימת התגובות וגם לפקס את שדה הקלט כשאתם לוחצים על הכפתור:
import { useRef } from 'react'; import Post from './Post.js'; export default function Page() { const postRef = useRef(null); function handleClick() { postRef.current.scrollAndFocusAddComment(); } return ( <> <button onClick={handleClick}> Write a comment </button> <Post ref={postRef} /> </> ); }