React'te bir ref için doğru prop türü nedir?


87

Redux mağazamda bir ref depoluyorum ve ona erişmesi gereken bileşenler için ref'i ortaya çıkarmak için mapStateToProps kullanıyorum.

Depolanan referans şuna benzer:

ref={node => this.myRefToBePutInReduxGlobalStore = node}

Bu referans için doğru propType nedir?


8
Referanslar serileştirilebilir olmadığından, onları Redux mağazasına koymak iyi bir fikir değildir. Bununla birlikte, refprop'a iletilen değer , ilk bağımsız değişkeni DOM öğesine veya null değerine gönderme yapan bir işlevdir. Bu bir işlev .
rishat

5
Sen kullanamazsınız propType için refs, ancak için kullanabilirsiniz props. Sonra redux mağazaya geçiyoruz beri bir şekilde temsil edilir propgibi this.props.myRefToBePutInReduxGlobalStore. myRefToBePutInReduxGlobalStoredüğüm türü PropTypes.nodeolmalıdır , bu yüzden sizin için çalışmalıdır
The Reason

Bence bu, PropType.objectref temelde nesne olan sınıf örneğidir. Bu nedenle, bir destek öğesi olarak ref öğesini
ilettiğinizde

Yanıtlar:


99

TL; DR

Yalnızca a divveya an gibi yerel DOM öğelerini bekleyen bir ref türünü desteklemek istiyorsanız input, doğru tanım şu şekildedir:

refProp: PropTypes.oneOfType([
    // Either a function
    PropTypes.func, 
    // Or the instance of a DOM native element (see the note about SSR)
    PropTypes.shape({ current: PropTypes.instanceOf(Element) })
])

Orijinal gönderide açıklanan belirli sorunu yanıtlayın

OP sorusu örneğinde, bildirilmesi gereken ref prop türü değil, ref tarafından gösterilen ve redux kullanılarak iletilecek olan şeylerdir mapStateToProps. Bir DOM öğesi için özellik türü şöyle olacaktır: myRefToBePutInReduxGlobalStore: PropTypes.instanceOf(Element)(bir DOM öğesi ise). Yine de yapardım:

  1. Bunu olarak yeniden adlandırın myElementToBePutInReduxGlobalStore(bir öğe bir ref değildir)
  2. Redux deposunda serileştirilemez verileri depolamaktan kaçının
  3. React mühendisi Seb Markbage tarafından açıklandığı gibi sahne öğelerinden geçiş yapmaktan kaçının

Asıl soruya uzun cevap

S: React'te bir ref için doğru prop türü nedir?

Örnek kullanım durumu:

function FancyInput({ inputRef }) {
    return (
        <div className="fancy">
            Fancy input
            <input ref={inputRef} />
        </div>
    )
}

FancyInput.propTypes = {
    inputRef: ???   // What is the correct prop type here?
}

function App(props) {
    const inputRef = React.useRef()
    useLayoutEffect(function focusWhenStuffChange() {
        inputRef.current?.focus()
    }, [props.stuff])
    return <FancyInput inputRef={inputRef} />
}

Bugün, react'te iki tür referans var:

  1. Şuna benzeyen bir nesne: { current: [something] }genellikle React.createRef()yardımcı veya React.useRef()kanca tarafından oluşturulan
  2. [something]Bağımsız değişken olarak alacak bir geri arama işlevi (OP örneğindeki gibi)

Not: Geçmişte, bir dize başvurusu da kullanabilirsiniz, ancak bu eski kabul edilir ve tepkiden kaldırılır

İkinci öğe oldukça basit ve aşağıdaki prop türünün kullanılmasını gerektirir: PropTypes.func.

İlk seçenek daha az belirgindir çünkü ref ile gösterilen öğe türünü belirtmek isteyebilirsiniz.

Çok iyi cevaplar

ref DOM öğesinden başka bir şeye işaret edebilir.

Tamamen esnek olmak istiyorsanız:

refProp: PropTypes.oneOfType([
    PropTypes.func, 
    PropTypes.shape({ current: PropTypes.any })
])

Yukarıdakiler sadece nesne ref w / currentproperty şeklini zorlar . Her türlü ref için her zaman çalışacaktır. Geliştirme sırasında herhangi bir tutarsızlığı tespit etmenin bir yolu olan pervane türünü kullanmak için , bu muhtemelen yeterlidir. Öyle görünüyor çok olası şekle sahip bir nesne olduğu { current: [any] }ve geçirilir refToForwardpervane, olur değil gerçek bir ref olacak.

Bununla birlikte , bileşeninizin herhangi bir ref beklemediğini , ancak ref için ihtiyaç duyduğu şey göz önüne alındığında yalnızca belirli bir tür beklediğini beyan etmek isteyebilirsiniz .

Bazıları geleneksel olmasa bile bir ref ilan etmenin birkaç farklı yolunu gösteren bir sandbox kurdum ve ardından bunları birçok pervane türüyle test ettim. Burada bulabilirsiniz .


Herhangi bir HTML değil, yalnızca yerel bir giriş öğesine işaret eden bir ref bekliyorsanız Element:

refProp: PropTypes.oneOfType([
    PropTypes.func, 
    PropTypes.shape({ current: PropTypes.instanceOf(HTMLInputElement) })
])

Yalnızca bir React sınıfı bileşenine işaret eden bir ref bekliyorsanız:

refProp: PropTypes.oneOfType([
    PropTypes.func, 
    PropTypes.shape({ current: PropTypes.instanceOf(Component) })
])

Yalnızca bir useImperativeHandlegenel yöntemi ortaya çıkarmak için bir işlevsel bileşene işaret eden bir ref bekliyorsanız :

refProp: PropTypes.oneOfType([
    PropTypes.func, 
    PropTypes.shape({ current: PropTypes.object })
])

Not: Yukarıdaki pervane türü ilginçtir çünkü react bileşenlerini ve yerel DOM öğelerini de kapsar, çünkü hepsi temel javascript'i miras alır. Object


Bir ref için prop tipini bildirmenin tek bir iyi yolu yoktur, bu kullanıma bağlıdır. Referansınız çok tanımlanmış bir şeye işaret ediyorsa, belirli bir pervane türü eklemeye değer olabilir. Aksi takdirde, sadece genel şekli kontrol etmek yeterli görünüyor.


Sunucu tarafında işleme hakkında not

Halihazırda çoklu doldurma DOM ortamınız yoksa kodunuzun sunucuda çalışması gerekiyorsa Elementveya başka herhangi bir istemci tarafı türü undefinedNodeJS'de olacaktır . Desteklemek için aşağıdaki şimi kullanabilirsiniz:

Element = typeof Element === 'undefined' ? function(){} : Element

Aşağıdaki React Docs sayfaları , hem nesne hem de geri çağrılar olmak üzere ref'lerin nasıl kullanılacağı ve ayrıca hook nasıl kullanılacağı hakkında daha fazla bilgi verir.useRef

Yanıt, @Rahul Sagore, @Ferenk Kamra, @svnm ve @Kamuela Franco'ya teşekkür olarak güncellendi


2
Bu verir Elementsunucu tarafında render üzerinde tanımlı değil. Buna herhangi bir çözüm var mı?
Rahul Sagore

İyi bir nokta. Peki ya bu şim: Element = typeof Element === 'undefined' ? function(){} : Element(Ryan Florence tarafından bazı github sayısında önerildi). Senin için çalışıyorsa cevabıma ekleyebilirim.
Pandaiolo

Anladım ve bunu ekledim if (!isBrowser) { global.Element = null; }. Benim için çalıştı. isBrowser = typeof window !== 'undefined';
Rahul Sagore

Mükemmel cevap. TL'nin yanıtın başında olmasını çok isterim.
Kamuela Franco

12

@ Pandaiolo'nun gönderisine çok benzer,

PropTypes.elementType şimdi eklendi

forwardedRef: PropTypes.oneOfType([
  PropTypes.func,
  PropTypes.shape({ current: PropTypes.elementType })
]),

PropTypes kullanılıyorsa> = 15.7.0 PropTypes.elementTypeyılında Şubat 10, 2019 eklendi bu PR


Teşekkürler @svnm, cevabımı bunu yansıtacak şekilde güncelledim, bu da daha basit hale getiriyor!
Pandaiolo

1
Sonunda, bu elementTypebenim için işe yaramadı, bu yüzden bir sandbox'ta bir ref ile işaret edilebilecek farklı türde bileşenler üzerinde bir grup pervane türünü test ettim. Sonuçlar şunlardır: codesandbox.io/s/loving-benz-w6fbh . Tüm olasılıkları ele aldığımdan emin değilim, ancak görünen o ki, DOM öğesi için doğru özellik instanceOf(Element)(veya object), bir sınıf için instanceOf(Component)(veya object) ve useImperativeHandleonu kullanan işlevsel bir bileşenin özel kullanım durumu için object. Düşünceler?
Pandaiolo

9

Yalnızca tercih edilen yolu kontrol ediyorum ve PropType.object çok değerli olmadığı için şunu kullandım:

PropTypes.shape({ current: PropTypes.instanceOf(Element) })

1

Yukarıdaki cevapların hepsini kontrol ettim ama tepkiden bir uyarı aldım, bu yüzden çok araştırdım ve doğru cevabı aldım.

import React, { Component } from 'react';

ComponentName.propTypes = {
  reference: PropTypes.oneOfType([
    PropTypes.func,
    PropTypes.shape({ current: PropTypes.instanceOf(Component) }),
  ]),
};
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.