Przechowuję referencję w moim sklepie redux i używam mapStateToProps do ujawnienia referencji dla komponentów, które potrzebują do niego dostępu.
Zapisany ref wygląda następująco:
ref={node => this.myRefToBePutInReduxGlobalStore = node}
Jaki jest poprawny typ propType dla tego odniesienia?
ref
jest funkcją, której pierwszy argument jest odniesieniem do elementu DOM lub null. To funkcja .propType
dlarefs
, ale możesz go użyć doprops
. Ponieważ przekazujesz go do sklepu Redux, jest on przedstawiony jakoprop
podobnythis.props.myRefToBePutInReduxGlobalStore
.myRefToBePutInReduxGlobalStore
powinien być typem węzła, więcPropTypes.node
powinien działać dla CiebiePropType.object
ponieważ ref jest w zasadzie instancją klasy, która jest obiektem. Stąd, gdy przekazujesz element ref jako rekwizyty, byłby to typ obiektuOdpowiedzi:
TL; DR
Jeśli chcesz wpisać ref, który oczekuje tylko natywnych elementów DOM, takich jak a
div
lub aninput
, prawidłowa definicja jest następująca: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) }) ])
Odpowiedz na konkretny problem opisany w oryginalnym poście
W przykładzie pytania OP to nie typ rekwizytu ref musi być zadeklarowany, ale rzeczy wskazywane przez ref, które zostaną przekazane przy użyciu reduxu
mapStateToProps
. Typ rekwizytu dla elementu DOM to:myRefToBePutInReduxGlobalStore: PropTypes.instanceOf(Element)
(jeśli jest to element DOM). Chociaż chciałbym:myElementToBePutInReduxGlobalStore
(element nie jest odniesieniem)Długa odpowiedź na aktualne pytanie
P: Jaki jest poprawny typ ref w React?
Przykład użycia:
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} /> }
Obecnie istnieją dwa rodzaje referencji:
{ current: [something] }
zwykle utworzony przezReact.createRef()
pomocnika lubReact.useRef()
hook[something]
jako argument (jak w przykładzie OP)Uwaga: historycznie można było również użyć ref w postaci ciągu znaków, ale jest to uważane za starsze i zostanie usunięte z reakcji
Druga pozycja jest bardzo prosta i wymaga następującego typu prop:
PropTypes.func
.Pierwsza opcja jest mniej oczywista, ponieważ możesz chcieć określić typ elementu wskazywanego przez ref.
Wiele dobrych odpowiedzi
ref
może wskazywać na coś innego niż element DOM.Jeśli chcesz być całkowicie elastyczny:
refProp: PropTypes.oneOfType([ PropTypes.func, PropTypes.shape({ current: PropTypes.any }) ])
Powyższe wymusza tylko kształt obiektu referencyjnego z
current
właściwością. Będzie działać przez cały czas dla każdego typu ref. W celu używania typu rekwizytu, który jest sposobem na wykrycie wszelkich niespójności podczas tworzenia , prawdopodobnie to wystarczy. Wydaje się bardzo mało prawdopodobne, aby obiekt posiadający kształt{ current: [any] }
i przekazany dorefToForward
rekwizytu nie był rzeczywistym odniesieniem.Jednak możesz chcieć zadeklarować, że twój komponent nie oczekuje żadnego rodzaju referencji, ale tylko określonego typu, biorąc pod uwagę, do czego potrzebuje tego ref.
Skonfigurowałem piaskownicę pokazującą kilka różnych sposobów deklarowania referencji, nawet niestandardowych, a następnie testowałem je z wieloma typami rekwizytów. Znajdziesz go tutaj .
Jeśli tylko oczekiwać wskazując ref do natywnego elementu wejściowego, nie każdy HTML
Element
:refProp: PropTypes.oneOfType([ PropTypes.func, PropTypes.shape({ current: PropTypes.instanceOf(HTMLInputElement) }) ])
Jeśli spodziewasz się tylko odniesienia wskazującego na komponent klasy React:
refProp: PropTypes.oneOfType([ PropTypes.func, PropTypes.shape({ current: PropTypes.instanceOf(Component) }) ])
Jeśli spodziewasz się tylko odniesienia wskazującego na komponent funkcjonalny, używając
useImperativeHandle
do ujawnienia jakiejś metody publicznej:refProp: PropTypes.oneOfType([ PropTypes.func, PropTypes.shape({ current: PropTypes.object }) ])
Uwaga: powyższy typ właściwości jest interesujący, ponieważ obejmuje również komponenty reagujące i natywne elementy DOM, ponieważ wszystkie dziedziczą podstawowy kod javascript
Object
Nie ma jednego dobrego sposobu na zadeklarowanie typu właściwości referencyjnej, zależy to od użycia. Jeśli Twoje odniesienie wskazuje na coś bardzo określonego, warto dodać określony typ rekwizytu. W przeciwnym razie wystarczy sprawdzić ogólny kształt.
Uwaga dotycząca renderowania po stronie serwera
Jeśli twój kod ma działać na serwerze, chyba że masz już polyfill środowiska DOM,
Element
lub inny typ po stronie klienta będzieundefined
w NodeJS. Możesz użyć następującej podkładki, aby ją podeprzeć:Element = typeof Element === 'undefined' ? function(){} : Element
Poniższe strony React Docs dają więcej informacji o tym, jak używać referencji, zarówno obiektu, jak i wywołań zwrotnych , a także jak używać
useRef
hookOdpowiedź zaktualizowana dzięki @Rahul Sagore, @Ferenk Kamra, @svnm i @Kamuela Franco
źródło
Element
nie jest zdefiniowane w renderowaniu po stronie serwera. Jakieś rozwiązanie?Element = typeof Element === 'undefined' ? function(){} : Element
(zasugerowana przez Ryana Florence w jakimś wydaniu na githubie). Jeśli to działa, mogę dodać to do mojej odpowiedzi.if (!isBrowser) { global.Element = null; }
. Pracował dla mnie.isBrowser = typeof window !== 'undefined';
Bardzo podobny do posta @ Pandaiolo,
PropTypes.elementType
został dodanyforwardedRef: PropTypes.oneOfType([ PropTypes.func, PropTypes.shape({ current: PropTypes.elementType }) ]),
W przypadku korzystania z PropTypes> = 15.7.0
PropTypes.elementType
zostało dodane 10 lutego 2019 r. W tym żądaniuźródło
elementType
to nie zadziałało, więc przetestowałem kilka typów rekwizytów na różnych rodzajach komponentów, które mogą być wskazywane przez ref, w piaskownicy. Oto wyniki: codeandbox.io/s/loving-benz-w6fbh . Nie jestem pewien, czy omówiłem wszystkie możliwości, ale wydaje się, że poprawnym typem właściwości elementu DOM jestinstanceOf(Element)
(lubobject
), dla klasy to jestinstanceOf(Component)
(lubobject
) i dla konkretnego przypadku użycia komponentu funkcjonalnego, któryuseImperativeHandle
go używaobject
. Myśli?Sprawdzam tylko preferowany sposób, a ponieważ PropType.object nie jest zbyt wartościowy, ostatecznie użyłem tego:
PropTypes.shape({ current: PropTypes.instanceOf(Element) })
źródło
Sprawdziłem wszystkie powyższe odpowiedzi, ale otrzymałem ostrzeżenie od reakcji, więc dużo szukałem i otrzymałem właściwą odpowiedź.
import React, { Component } from 'react'; ComponentName.propTypes = { reference: PropTypes.oneOfType([ PropTypes.func, PropTypes.shape({ current: PropTypes.instanceOf(Component) }), ]), };
źródło