forwardRef
உங்கள் component parent component-க்கு ref மூலம் DOM node expose செய்ய forwardRef உதவுகிறது.
const SomeComponent = forwardRef(render)குறிப்பு
forwardRef(render)
உங்கள் component ref பெறவும் அதை child component-க்கு forward செய்யவும் forwardRef()-ஐ call செய்யுங்கள்:
import { forwardRef } from 'react';
const MyInput = forwardRef(function MyInput(props, ref) {
// ...
});மேலும் உதாரணங்களை கீழே பார்க்கவும்.
Parameters
render: உங்கள் component-க்கான render function. Parent-இலிருந்து உங்கள் component பெற்ற props மற்றும்refஉடன் React இந்த function-ஐ call செய்யும். நீங்கள் return செய்யும் JSX உங்கள் component-ன் output ஆக இருக்கும்.
Returns
forwardRef JSX-இல் render செய்யக்கூடிய React component-ஐ return செய்கிறது. Plain functions ஆக define செய்யப்பட்ட React components போல அல்லாமல், forwardRef return செய்யும் component ref prop-ஐயும் பெற முடியும்.
Caveats
- Strict Mode-இல், தற்செயலான impurities கண்டுபிடிக்க உதவ React உங்கள் render function-ஐ இரண்டு முறை call செய்யும். இது development-only behavior; production-ஐ பாதிக்காது. உங்கள் render function pure என்றால் (அப்படித்தான் இருக்க வேண்டும்), இது உங்கள் component-ன் logic-ஐ பாதிக்காது. Calls-இல் ஒன்றின் result புறக்கணிக்கப்படும்.
render function
forwardRef render function-ஐ argument ஆக ஏற்கிறது. React இந்த function-ஐ props மற்றும் ref உடன் call செய்யும்:
const MyInput = forwardRef(function MyInput(props, ref) {
return (
<label>
{props.label}
<input ref={ref} />
</label>
);
});Parameters
-
props: Parent component pass செய்த props. -
ref: Parent component pass செய்தrefattribute.refobject அல்லது function ஆக இருக்கலாம். Parent component ref pass செய்யவில்லை என்றால், அதுnullஆக இருக்கும். நீங்கள் பெறும்ref-ஐ மற்றொரு component-க்கு pass செய்யவேண்டும், அல்லதுuseImperativeHandle-க்கு pass செய்ய வேண்டும்.
Returns
forwardRef JSX-இல் render செய்யக்கூடிய React component-ஐ return செய்கிறது. Plain functions ஆக define செய்யப்பட்ட React components போல அல்லாமல், forwardRef return செய்யும் component ref prop-ஐ ஏற்க முடியும்.
பயன்பாடு
Parent component-க்கு DOM node expose செய்தல்
Default-ஆக, ஒவ்வொரு component-ன் DOM nodes private. ஆனால் சில நேரங்களில் DOM node-ஐ parent-க்கு expose செய்வது பயனுள்ளதாக இருக்கும்; உதாரணமாக, அதை focus செய்ய அனுமதிக்க. இதற்கு opt in செய்ய, உங்கள் component definition-ஐ forwardRef()-க்குள் wrap செய்யுங்கள்:
import { forwardRef } from 'react';
const MyInput = forwardRef(function MyInput(props, ref) {
const { label, ...otherProps } = props;
return (
<label>
{label}
<input {...otherProps} />
</label>
);
});Props-க்கு பிறகு இரண்டாவது argument ஆக ref பெறுவீர்கள். Expose செய்ய விரும்பும் DOM node-க்கு அதை pass செய்யுங்கள்:
import { forwardRef } from 'react';
const MyInput = forwardRef(function MyInput(props, ref) {
const { label, ...otherProps } = props;
return (
<label>
{label}
<input {...otherProps} ref={ref} />
</label>
);
});இதனால் parent Form component, MyInput expose செய்த <input> DOM node-ஐ access செய்ய முடியும்:
function Form() {
const ref = useRef(null);
function handleClick() {
ref.current.focus();
}
return (
<form>
<MyInput label="Enter your name:" ref={ref} />
<button type="button" onClick={handleClick}>
Edit
</button>
</form>
);
}இந்த Form component MyInput-க்கு ref pass செய்கிறது. MyInput component அந்த ref-ஐ <input> browser tag-க்கு forward செய்கிறது. அதன் விளைவாக, Form component அந்த <input> DOM node-ஐ access செய்து அதில் focus() call செய்ய முடியும்.
உங்கள் component-க்குள் உள்ள DOM node-க்கு ref expose செய்வது, பின்னர் component internals மாற்றுவதைக் கடினமாக்கும் என்பதை நினைவில் கொள்ளுங்கள். பொதுவாக buttons அல்லது text inputs போன்ற reusable low-level components-இலிருந்து DOM nodes expose செய்வீர்கள்; avatar அல்லது comment போன்ற application-level components-க்கு இதைச் செய்யமாட்டீர்கள்.
Example 1 of 2: Text input-ஐ focus செய்தல்
Button click செய்தால் input focus ஆகும். Form component ref define செய்து அதை MyInput component-க்கு pass செய்கிறது. MyInput component அந்த ref-ஐ browser <input>-க்கு forward செய்கிறது. இதனால் Form component <input>-ஐ focus செய்ய முடியும்.
import { useRef } from 'react'; import MyInput from './MyInput.js'; export default function Form() { const ref = useRef(null); function handleClick() { ref.current.focus(); } return ( <form> <MyInput label="Enter your name:" ref={ref} /> <button type="button" onClick={handleClick}> Edit </button> </form> ); }
பல components வழியாக ref forward செய்தல்
ref-ஐ DOM node-க்கு forward செய்வதற்கு பதிலாக, MyInput போன்ற உங்கள் சொந்த component-க்கு forward செய்யலாம்:
const FormField = forwardRef(function FormField(props, ref) {
// ...
return (
<>
<MyInput ref={ref} />
...
</>
);
});அந்த MyInput component ref-ஐ அதன் <input>-க்கு forward செய்தால், FormField-க்கு கொடுக்கப்படும் ref அந்த <input>-ஐ தரும்:
function Form() {
const ref = useRef(null);
function handleClick() {
ref.current.focus();
}
return (
<form>
<FormField label="Enter your name:" ref={ref} isRequired={true} />
<button type="button" onClick={handleClick}>
Edit
</button>
</form>
);
}Form component ref define செய்து அதை FormField-க்கு pass செய்கிறது. FormField component அந்த ref-ஐ MyInput-க்கு forward செய்கிறது; MyInput அதை browser <input> DOM node-க்கு forward செய்கிறது. இதுவே Form அந்த DOM node-ஐ access செய்வது.
import { useRef } from 'react'; import FormField from './FormField.js'; export default function Form() { const ref = useRef(null); function handleClick() { ref.current.focus(); } return ( <form> <FormField label="Enter your name:" ref={ref} isRequired={true} /> <button type="button" onClick={handleClick}> Edit </button> </form> ); }
DOM node-க்கு பதிலாக imperative handle expose செய்தல்
முழு DOM node-ஐ expose செய்வதற்கு பதிலாக, குறுகிய methods தொகுப்புடன் imperative handle என்று அழைக்கப்படும் custom object-ஐ expose செய்யலாம். இதை செய்ய, DOM node-ஐ hold செய்ய தனி ref define செய்ய வேண்டும்:
const MyInput = forwardRef(function MyInput(props, ref) {
const inputRef = useRef(null);
// ...
return <input {...props} ref={inputRef} />;
});நீங்கள் பெற்ற ref-ஐ useImperativeHandle-க்கு pass செய்து, ref-க்கு expose செய்ய வேண்டிய value-ஐ குறிப்பிடுங்கள்:
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} />;
});ஏதாவது component MyInput-க்கு ref பெற்றால், DOM node-க்கு பதிலாக உங்கள் { focus, scrollIntoView } object மட்டும் பெறும். இதனால் உங்கள் DOM node பற்றிய நீங்கள் expose செய்யும் information-ஐ குறைந்தபட்சமாக கட்டுப்படுத்தலாம்.
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 handles பயன்படுத்துவது குறித்து மேலும் படிக்கவும்.
சிக்கல் தீர்வு
என் component forwardRef-இல் wrap செய்யப்பட்டுள்ளது, ஆனால் அதற்கான ref எப்போதும் null ஆக உள்ளது
பொதுவாக இதன் அர்த்தம்: நீங்கள் பெற்ற ref-ஐ உண்மையில் பயன்படுத்த மறந்துவிட்டீர்கள்.
உதாரணமாக, இந்த component தனது ref உடன் எதையும் செய்யவில்லை:
const MyInput = forwardRef(function MyInput({ label }, ref) {
return (
<label>
{label}
<input />
</label>
);
});இதைக் சரிசெய்ய, ref-ஐ DOM node-க்கோ அல்லது ref ஏற்கக்கூடிய மற்றொரு component-க்கோ கீழே pass செய்யுங்கள்:
const MyInput = forwardRef(function MyInput({ label }, ref) {
return (
<label>
{label}
<input ref={ref} />
</label>
);
});Logic-இன் சில பகுதி conditional என்றால், MyInput-க்கான ref-உம் null ஆக இருக்கலாம்:
const MyInput = forwardRef(function MyInput({ label, showInput }, ref) {
return (
<label>
{label}
{showInput && <input ref={ref} />}
</label>
);
});showInput false என்றால், ref எந்த node-க்கும் forward செய்யப்படாது; MyInput-க்கான ref empty ஆக இருக்கும். இந்த உதாரணத்தில் உள்ள Panel போல condition மற்றொரு component-க்குள் மறைந்திருந்தால், இதை தவறவிடுவது சாத்தியம்:
const MyInput = forwardRef(function MyInput({ label, showInput }, ref) {
return (
<label>
{label}
<Panel isExpanded={showInput}>
<input ref={ref} />
</Panel>
</label>
);
});