Ref'leri Yönlendirme
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 yönlendirme bir ref‘i üst bileşenlerden alt bileşenlerin birine otomatik olarak aktarma tekniğidir. Bu genellikle uygulamadaki çoğu bileşen için gerekli değildir. Ama bazı bileşen türleri için faydalı olabilir, özellikle yeniden kullanılabilir bileşen kütüphaneleri için. En yaygın senaryolar aşağıda açıklanmaktadır.
Ref’leri DOM bileşenlerine aktarmak
Yerel (native) button
öğesini oluşturan FancyButton
bileşenini düşünün:
function FancyButton(props) {
return (
<button className="FancyButton">
{props.children}
</button>
);
}
React bileşenleri, render edilen çıktıları da dahil olacak bir şekilde uygulama ayrıntılarını gizler. FancyButton
bileşenini kullanan diğer bileşenler, alt button
DOM elemanı için genellikle gerekmeyen ref elde ederler.. Bu iyi bir şeydir, çünkü bileşenlerin birbirilerinin DOM yapısına fazla bağımlı olmasını önler.
Her ne kadar bu kapsülleme (encapsulation) FeedStory
veya Comment
gibi uygulama seviyesi bileşenler için arzu edilse de, FancyButton
veya MyTextInput
gibi yüksek oranda yeniden kullanılabilir “yaprak” bileşenler için sakıncalı olabilir. Bu bileşenler uygulama boyunca normal bir DOM button
ve input
öğeleri gibi benzer şekilde kullanılma eğilimindedir, odaklama, seçim veya animasyonları yönetmek için DOM düğümlerine erişmek kaçınılmaz olabilir.
Ref yönlendirme, bazı bileşenlerin aldıkları bir ref’i almasını ve daha alt elemente aktarmasını sağlayan bir etkinleştirme özelliğidir
Alttaki örnekte, FancyButton
kendisine aktarılan ref’i elde etmek için React.forwardRef
kullanılır ve ardından oluşturduğu DOM button
‘a iletir:
const FancyButton = React.forwardRef((props, ref) => ( <button ref={ref} className="FancyButton"> {props.children}
</button>
));
// You can now get a ref directly to the DOM button:
const ref = React.createRef();
<FancyButton ref={ref}>Click me!</FancyButton>;
Bu şekilde, FancyButton
kullanan bileşenler, temelde bulunan button
DOM düğümüne bir ref oluşturabilir ve gerekirse doğrudan bir DOM button
kullanmış gibi erişebilir.
Yukarıdaki örnekte neler olduğuna dair adım adım açıklama:
React.createRef
‘i çağırarak bir React ref oluşturuyoruz veref
değişkenine atama yapıyoruz.- JSX özelliği olarak belirterek
ref
‘i<FancyButton ref={ref}>
bileşenine aktarıyoruz. - React, ikinci bir argüman olarak
ref
‘yiforwardRef
içindeki(props, ref) => ...
fonksiyonuna iletir. - JSX özelliği olarak belirterek,
ref
argümanını<button ref={ref}>
‘a aktarıyoruz. - Ref eklendiğinde.
ref.current
,<button>
DOM düğmüne işaret edecektir.
Not
İkinci
ref
argümanı yalnızcaReact.forwardRef
çağrısıyla oluşur. Normal fonksiyon veya sınıf bileşenleriref
argümanı almaz, ayrıca ref prop’larda da mevcut değildir.Ref yönlendirme yalnızca DOM bileşenleri ile sınırlı değildir. ref’leri sınıf bileşenlerinden türetilen nesnelere de aktarabilirsiniz.
Bileşen kütüphanesine bakım yapanlara not
forwardRef
‘i bir bileşen içinde kullanmaya başladığınızda, Bunu tehlikeli bir değişim olarak değerlendirmelisiniz ve yeni bir sürüm yayınlamalısınız. Bunun nedeni, kütüphanenizin büyük olasılıkla gözle görülür şekilde farklı bir yaklaşıma sahip olmasıdır (ref’lerin ataması ve hangi türlerin dışa aktarıldığı gibi), ve eski yaklaşıma bağlı uygulamaları ve diğer kütüphaneleri etkiliyebilir.
Mevcut olduğunda React.forwardRef
‘i koşullu olarak uygulamak da aynı nedenlerle önerilmez:
Kütüphanenizin biçimini değiştirir ve React’i yükselttiklerinde kullanıcılarınızın uygulamalarını bozabilir.
Üst-Seviye Bileşenlerde ref’leri yönlendirme
Bu teknik, üst-seviye bileşenlerde özellikle yararlı olabilir higher-order components (HOC olarak da bilinir). Konsola bileşen prop’larını yazdıran örnek bir HOC ile başlayalım:
function logProps(WrappedComponent) { class LogProps extends React.Component {
componentDidUpdate(prevProps) {
console.log('old props:', prevProps);
console.log('new props:', this.props);
}
render() {
return <WrappedComponent {...this.props} />; }
}
return LogProps;
}
“logProps” HOC, tüm prop’ları kapladığı bileşene aktarır, böylece sonuç aynı olacaktır. Örneğin, “fancy button” bileşenimize iletilen tüm prop’ları yazdırmak için bu HOC’u kullanabiliriz.
class FancyButton extends React.Component {
focus() {
// ...
}
// ...
}
// Rather than exporting FancyButton, we export LogProps.
// It will render a FancyButton though.
export default logProps(FancyButton);
Yukarıdaki örnekle ilgili bir uyarı: ref’ler iletilmeyecek. Bunun nedeni ref
prop değildir. key
gibi, React tarafından farklı şekilde ele alınır. Bir HOC’a ref eklerseniz ref, kaplanmış bileşene değil, en dıştaki kapsaycı bileşene atıfta bulunacaktır.
Bu, FancyButton
bileşeni için istenilen ref’lerin aslında LogProps
bileşenine ekleneceği anlamına gelir.
import FancyButton from './FancyButton';
const ref = React.createRef();
// The FancyButton component we imported is the LogProps HOC.
// Even though the rendered output will be the same,
// Our ref will point to LogProps instead of the inner FancyButton component!
// This means we can't call e.g. ref.current.focus()
<FancyButton
label="Click Me"
handleClick={handleClick}
ref={ref}/>;
Neyse ki, ref’leri React.forwardRef
API’ını kullanarak iç FancyButton
bileşenine iletebiliriz. React.forwardRef
, props
ve ref
parametrelerini alan ve bir React düğüm’u döndüren render fonksiyonu kabul eder. Örneğin:
function logProps(Component) {
class LogProps extends React.Component {
componentDidUpdate(prevProps) {
console.log('old props:', prevProps);
console.log('new props:', this.props);
}
render() {
const {forwardedRef, ...rest} = this.props;
// Assign the custom prop "forwardedRef" as a ref
return <Component ref={forwardedRef} {...rest} />; }
}
// Note the second param "ref" provided by React.forwardRef.
// We can pass it along to LogProps as a regular prop, e.g. "forwardedRef"
// And it can then be attached to the Component.
return React.forwardRef((props, ref) => { return <LogProps {...props} forwardedRef={ref} />; });}
DevTools’ta özel bir ad görüntüleme
React.forwardRef
render fonksiyonu kabul eder. React DevTools, ref yönlendirme bileşeni için neyin görüntüleneceğini belirlemek için bu fonksiyonu kullanır.
Örneğin, aşağıdaki bileşen DevTools’ta ”ForwardRef” olarak görünür
const WrappedComponent = React.forwardRef((props, ref) => {
return <LogProps {...props} forwardedRef={ref} />;
});
Oluşturma fonksiyonunu adlandırırsanız, DevTools ayrıca adını da ekler (örn. ”ForwardRef(myFunction)”):
const WrappedComponent = React.forwardRef(
function myFunction(props, ref) {
return <LogProps {...props} forwardedRef={ref} />;
}
);
Hatta fonksiyonun displayName
özelliğini kapladığınız bileşeni içerecek şekilde ayarlayabilirsiniz:
function logProps(Component) {
class LogProps extends React.Component {
// ...
}
function forwardRef(props, ref) {
return <LogProps {...props} forwardedRef={ref} />;
}
// Give this component a more helpful display name in DevTools.
// e.g. "ForwardRef(logProps(MyComponent))"
const name = Component.displayName || Component.name; forwardRef.displayName = `logProps(${name})`;
return React.forwardRef(forwardRef);
}