Ref-lərin Yönləndirilməsi
These docs are old and won’t be updated. Go to react.dev for the new React docs.
These new documentation pages teach modern React and include live examples:
Ref-in yönləndirilməsi - avtomatik ref komponentinin içindən onun bir uşağına ötürülməsi texnikasıdır. Bu texnika çox vaxt applikasiyadakı komponentlər üçün vacib deyil. Lakin, bəzi növ komponentlər üçün, xüsusilə yenidən istifadə olunan komponent kitabxanalarında, faydalı ola bilər. Çox vaxt rast gəlinən ssenarilər aşağıda qeyd olunub.
DOM komponentlərinə ref-lərin yönləndirilməsi
Nativ button
DOM elementini render edən FancyButton
komponentinə nəzər salın:
function FancyButton(props) {
return (
<button className="FancyButton">
{props.children}
</button>
);
}
React komponentləri tətbiq detallarını, eləcə də onların render edilmiş nəticələrini gizlədir. Adətən FancyButton
istifadə edən digər komponenlər FancyButton
-ın daxili button
DOM elementində olan ref-i əldə etmək üçün lazım deyil. Bu yaxşıdır, çünki bu elementlərin bir-birinin DOM strukturlarından çox arxayın olmağının qarşısını alır.
Buna baxmayaraq, belə inkapsulyasiyalar FeedStory
və ya Comment
kimi applikasiya-səviyyəli komponentlər üçün arzu olunandır. Bu FancyButton
və ya MyTextInput
kimi yüksək dərəcəli yenidən istifadə edilə bilən “leaf” komponentləri üçün əlverişsiz ola bilər. Bu komponentlər applikasiya boyunca bənzər bir şəkildə müntəzən DOM button
və input
kimi istifadə edilməyə meyillidir və onların DOM nodlarına fokus, seçmə və ya animasiyalar üçün girişi qaçılmazdır.
Ref-in yönləndirilməsi, komponentlərin qəbul etdikləri ref
-i daha aşağı uşağa göndərməsi (başqa sözlə “yönləndirməsi”) xüsusiyyətidir.
Aşağıdakı nümunədə FancyButton
, ona ötürülmüş ref
-i əldə etmək üçün React.forwardRef
istifadə edir və sonra onu render edən DOM button
-a yönləndirir:
const FancyButton = React.forwardRef((props, ref) => ( <button ref={ref} className="FancyButton"> {props.children}
</button>
));
// İndi siz ref-i birdəfəlik DOM button-a ötürə bilərsiniz:
const ref = React.createRef();
<FancyButton ref={ref}>Click me!</FancyButton>;
Bu yolla FancyButton
istifadə edən komponentlər, FancyButton
-da yerləşən button
DOM nodunun ref-ini əldə edə bilər və bu ref
ilə DOM button
-dan birbaşa istifadə etdiyimiz kimi, FancyButton
-dakı button
DOM nodundan istifadə edə bilərik.
Yuxarıdakı misalın addım-addım izahatına aşağıda baxa bilərsiniz:
- Biz
React.createRef
çağıraraq React ref yaradırıq və onuref
dəyişəninə təyin edirik. - Biz
ref
-imizi JSX atributu kimi təyin edərək<FancyButton ref={ref}>
komponentinə ötürürük. - React
ref
-iforwardRef
funksiyasının içində olan(props, ref) => ...
funksiyasının ikinci arqumentinə ötürür. - Biz bu
ref
arqumentini JSX atributu kimi təyin edərək<button ref={ref}>
komponentinə yönləndiririk. - ref qoşulduğu zaman,
ref.current
-i<button>
DOM nodu göstərəcək.
Qeyd
Siz yalnız komponenti
React.forwardRef
ilə çağırışı ilə təyin etdikdə, ikinciref
arqumenti mövcud olacaqdır. Müntəzəm funksiya və ya sinif komponentləriref
arqumentini qəbul etmir və ref proplarda da əlçatan deyil.Ref-in yönləndirilməsi DOM komponentləri ilə limitli deyil. Siz həmçinin ref-ləri sinif komponentlərinin nümunələrinə yönləndirə bilərsiniz.
Komponent Kitabxana saxlayıcıları üçün qeyd
Komponent kitabxanasında forwardRef
istifadə etdikdə, siz onu sına bilən dəyişən kimi saxlamalı və öz kitabxananızın yeni böyük versiyasını yayımlamalısınız. Bu çox gümanki sizin kitabxananızın gözlənilən fərqli davranışı olduğu üçündür (məsələn, hansı ref-lərin təyin edildiyi, hansı növlərin ixrac edildiyi) və bu keçmiş davranışdan asılı olan applikasiyaları və digər kitabxanaları sındıra bilər.
Şərti şəkildə mövcud olduğu zaman React.forwardRef
-i tətbiq etmək bəzi səbəblərə görə məsləhət görülmür: bu sizin kitabxananızın davranışını dəyişir və React-in özünü yenilədikdə etdikdə sizin istifadəçilərinizin applikasiyaları sınmasına səbəb ola bilər.
Yüksək qaydada komponentlərdə ref-lərin yönləndirilməsi
Bu metod yüksək qaydada komponentlər (higher-order components və ya HOCs) ilə xüsusilə faydalı ola bilər. Gəlin konsola komponent proplarının qeydiyyatını edən HOC-un misalı ilə başlayaq:
function logProps(WrappedComponent) { class LogProps extends React.Component {
componentDidUpdate(prevProps) {
console.log('köhnə proplar:', prevProps);
console.log('yeni proplar:', this.props);
}
render() {
return <WrappedComponent {...this.props} />; }
}
return LogProps;
}
“logProps” HOC-i, bütün propları
onu əhatə edən komponentdən keçirir, beləliklə render edilmiş nəticə eyni olur. Misal üçün, biz bu HOC-ni bizim “fancy button” komponentimizə ötən bütün propları qeydiyyata almaq üçün istifadə edə bilərik:
class FancyButton extends React.Component {
focus() {
// ...
}
// ...
}
// FancyButton-u eksport etməkdənsə, biz LogProps-u eksport edirik.
// Buna baxmayaraq, bu FancyButton-u render edəcək.
export default logProps(FancyButton);
Yuxarıdakı nümunədə bir xəbərdarlıq var: ref-lər ötməyəcəklər. Bunun səbəbi ref
-in prop olmamağıdır. key
kimi bu React-də fərqli işlənir. Əgər siz HOC-aəref əlavə etsəniz, ref əhatə olunmuş komponentə deyil, ən xarici konteyner komponentinə müraciət edəcək.
Bu deməkdir ki, FancyButton
-da komponentimiz üçün nəzərdə tutulmuş ref-lər faktiki olaraq LogProps
komponentinə qoşulacaq:
import FancyButton from './FancyButton';
const ref = React.createRef();
// Bizim import etmidiyimiz FancyButton komponenti LogProps HOC-dur.
// Hətta renden edilmiş nəticə də eyni olacaq,
// Bizim ref-imiz daxili FancyButton komponentinin yerinə LogProps-a işarə edəcək!
// Bu deməkdir ki, biz məsələn ref.current.focus() çağıra bilmərik
<FancyButton
label="Click Me"
handleClick={handleClick}
ref={ref}/>;
Xoşbəxtlikdən, biz React.forwardRef
API istifadə edərək açıq şəkildə ref-ləri FancyButton
daxili komponentinə yönləndirə bilərik. React.forwardRef
, props
və ref
parametrlərini qəbul edən və React nodu qaytaran render funksiyasını qəbul edir. Məsələn:
function logProps(Component) {
class LogProps extends React.Component {
componentDidUpdate(prevProps) {
console.log('köhnə proplar:', prevProps);
console.log('yeni proplar:', this.props);
}
render() {
const {forwardedRef, ...rest} = this.props;
// Xüsusi prop "forwardedRef"-ı ref kimi təyin edin
return <Component ref={forwardedRef} {...rest} />; }
}
// Nəzər alın ki, ikinci "ref" parametri React.forwardRef. tərəfindən təqdim olunub.
// Biz bunu LogProps-a müntəzəm prop kimi ötürə bilərik, məs. "forwardedRef"
// Və sonra bu Komponent kimi qoşula bilər.
return React.forwardRef((props, ref) => { return <LogProps {...props} forwardedRef={ref} />; });}
DevTools-da xüsusi adların göstərilməsi
React.forwardRef
render funksiyasını qəbul edir. React DevTools, bu funksiyanı ref-in yönləndirilməsi komponentinin nə göstərəcəyini müəyyən etməsi üçün istifadə edir.
Misal üçün, növbəti komponent DevTools-da ”ForwardRef” kimi görünəcək:
const WrappedComponent = React.forwardRef((props, ref) => {
return <LogProps {...props} forwardedRef={ref} />;
});
Əgər siz render funksiyasını adlandırsanız, DevTools da onun adını əlavə edəcək (məsələn: ”ForwardRef(myFunction)”):
const WrappedComponent = React.forwardRef(
function myFunction(props, ref) {
return <LogProps {...props} forwardedRef={ref} />;
}
);
Siz hətta funksiyanın displayName
parametrini əhatə etdiyiniz komponentin adını daxil etmək üçün də quraşdıra bilərsiniz:
function logProps(Component) {
class LogProps extends React.Component {
// ...
}
function forwardRef(props, ref) {
return <LogProps {...props} forwardedRef={ref} />;
}
// DevTools-da bu komponentə daha faydalı təsvir adı ver.
// məsələn "ForwardRef(logProps(MyComponent))"
const name = Component.displayName || Component.name; forwardRef.displayName = `logProps(${name})`;
return React.forwardRef(forwardRef);
}