Ich speichere eine Referenz in meinem Redux-Speicher und verwende mapStateToProps, um die Referenz für Komponenten verfügbar zu machen, die Zugriff darauf benötigen.
Die gespeicherte Referenz sieht folgendermaßen aus:
ref={node => this.myRefToBePutInReduxGlobalStore = node}
Was ist der richtige PropType für diese Referenz?
ref
prop übergebene Wert ist jedoch eine Funktion, bei der das erste Argument auf das DOM-Element oder null verweist. Es ist eine Funktion .propType
für verwendenrefs
, aber Sie können es für verwendenprops
. Da Sie es zu redux Speicher sind vorbei , dann wird es als dargestelltprop
wiethis.props.myRefToBePutInReduxGlobalStore
.myRefToBePutInReduxGlobalStore
sollte der Knotentyp sein,PropTypes.node
sollte also für Sie funktionierenPropType.object
weil ref im Grunde eine Klasseninstanz ist, die ein Objekt ist. Daher , wenn Sie ref - Element als Requisiten passieren würde es sein Objekt TypAntworten:
TL; DR
Wenn Sie eine Referenz eingeben möchten, die nur native DOM-Elemente wie a
div
oder an erwartetinput
, lautet die richtige Definition wie folgt: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) }) ])
Beantworten Sie das im ursprünglichen Beitrag beschriebene Problem
Im Beispiel der OP-Frage muss nicht der Ref-Prop-Typ deklariert werden, sondern das Material, auf das der Ref zeigt, und das von Redux mit übergeben wird
mapStateToProps
. Der Prop-Typ für ein DOM-Element wäre:myRefToBePutInReduxGlobalStore: PropTypes.instanceOf(Element)
(wenn es sich um ein DOM-Element handelt). Obwohl ich würde:myElementToBePutInReduxGlobalStore
(ein Element ist kein ref)Lange Antwort auf die eigentliche Frage
F: Was ist der richtige Proptyp für einen Ref in React?
Beispiel für einen Anwendungsfall:
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} /> }
Heute gibt es zwei Arten von Refs, um zu reagieren:
{ current: [something] }
normalerweise von einemReact.createRef()
Helfer oderReact.useRef()
Haken erstellt[something]
als Argument empfangen wird (wie im OP-Beispiel)Hinweis: In der Vergangenheit konnten Sie auch eine Zeichenfolgenreferenz verwenden, diese wird jedoch als Legacy betrachtet und aus der Reaktion entfernt
Der zweite Punkt ist recht einfach und erfordert den folgenden Requisitentyp :
PropTypes.func
.Die erste Option ist weniger offensichtlich, da Sie möglicherweise den Elementtyp angeben möchten, auf den die Referenz zeigt.
Viele gute Antworten
ref
kann auf etwas anderes als ein DOM-Element verweisen.Wenn Sie völlig flexibel sein möchten:
refProp: PropTypes.oneOfType([ PropTypes.func, PropTypes.shape({ current: PropTypes.any }) ])
Das Obige erzwingt nur die Form des Objekts ref w /
current
property. Es wird jederzeit für jede Art von Ref funktionieren. Für die Verwendung des Requisitentyps, mit dem Inkonsistenzen bei der Entwicklung erkannt werden können , ist dies wahrscheinlich ausreichend. Es ist sehr unwahrscheinlich, dass ein Objekt mit Form{ current: [any] }
, das an einerefToForward
Requisite übergeben wird, keine tatsächliche Referenz ist.Allerdings möchten Sie vielleicht, erklären , dass Ihre Komponente nicht erwartet aus jeder Art von ref, sondern nur eine bestimmte Art, gegeben , was es für diese ref benötigt.
Ich habe eine Sandbox eingerichtet, die einige verschiedene Möglichkeiten zeigt, einen Ref zu deklarieren, auch einige nicht konventionelle, und sie dann mit vielen Requisitentypen zu testen. Sie finden es hier .
Wenn Sie nur einen ref zeigt auf einem nativen Eingabeelement erwarten, nicht jede HTML
Element
:refProp: PropTypes.oneOfType([ PropTypes.func, PropTypes.shape({ current: PropTypes.instanceOf(HTMLInputElement) }) ])
Wenn Sie nur einen Verweis erwarten, der auf eine React-Klassenkomponente verweist:
refProp: PropTypes.oneOfType([ PropTypes.func, PropTypes.shape({ current: PropTypes.instanceOf(Component) }) ])
Wenn Sie nur einen Verweis erwarten, der auf eine Funktionskomponente verweist, mit der eine
useImperativeHandle
öffentliche Methode verfügbar gemacht wird:refProp: PropTypes.oneOfType([ PropTypes.func, PropTypes.shape({ current: PropTypes.object }) ])
Hinweis: Der obige Requisitentyp ist interessant, da er auch Reaktionskomponenten und native DOM-Elemente abdeckt, da alle das Basis-Javascript erben
Object
Es gibt keine gute Möglichkeit, den Requisitentyp für eine Referenz zu deklarieren. Dies hängt von der Verwendung ab. Wenn Ihr Schiedsrichter auf etwas sehr Identifiziertes verweist, kann es sich lohnen, einen bestimmten Requisitentyp hinzuzufügen. Andernfalls reicht es aus, nur die allgemeine Form zu überprüfen.
Hinweis zum serverseitigen Rendern
Wenn Ihr Code auf dem Server ausgeführt werden muss, es sei denn, Sie haben bereits eine DOM-Umgebung mit Polyfill gefüllt ,
Element
oder ein anderer clientseitiger Typ befindet sichundefined
in NodeJS. Sie können das folgende Shim verwenden, um es zu unterstützen:Element = typeof Element === 'undefined' ? function(){} : Element
Auf den folgenden React Docs-Seiten finden Sie weitere Informationen zur Verwendung von Refs, sowohl Objekt- als auch Rückrufaktionen , sowie zur Verwendung von
useRef
HooksAntwort aktualisiert dank @Rahul Sagore, @Ferenk Kamra, @svnm und @Kamuela Franco
quelle
Element
wird beim serverseitigen Rendern nicht definiert. Irgendeine Lösung dafür?Element = typeof Element === 'undefined' ? function(){} : Element
(vorgeschlagen von Ryan Florence in einer Github-Ausgabe). Wenn es für Sie funktioniert, kann ich es meiner Antwort hinzufügen.if (!isBrowser) { global.Element = null; }
. Hat für mich gearbeitet.isBrowser = typeof window !== 'undefined';
Sehr ähnlich zu @ Pandaiolos Beitrag,
PropTypes.elementType
wurde jetzt hinzugefügtforwardedRef: PropTypes.oneOfType([ PropTypes.func, PropTypes.shape({ current: PropTypes.elementType }) ]),
Bei Verwendung von PropTypes> = 15.7.0
PropTypes.elementType
wurde in dieser PR der 10. Februar 2019 hinzugefügtquelle
elementType
bei mir nicht funktioniert, also habe ich tatsächlich eine Reihe von Requisitentypen an verschiedenen Arten von Komponenten getestet, auf die ein Schiedsrichter in einem Sandkasten zeigen kann. Hier sind die Ergebnisse: Codesandbox.io/s/loving-benz-w6fbh . Ich bin nicht sicher, ob ich alle Möglichkeiten abgedeckt habe, aber es scheint, dass der richtige Proptyp für das DOM-ElementinstanceOf(Element)
(oderobject
) ist, für eine KlasseinstanceOf(Component)
(oderobject
) und für den spezifischen Anwendungsfall einer Funktionskomponente, dieuseImperativeHandle
es verwendetobject
. Gedanken?Ich überprüfe nur den bevorzugten Weg und da PropType.object nicht sehr wertvoll ist, habe ich Folgendes verwendet:
PropTypes.shape({ current: PropTypes.instanceOf(Element) })
quelle
Ich habe alle oben genannten Antworten überprüft, aber ich bekomme eine Warnung von der Reaktion, also habe ich viel recherchiert und die richtige Antwort erhalten.
import React, { Component } from 'react'; ComponentName.propTypes = { reference: PropTypes.oneOfType([ PropTypes.func, PropTypes.shape({ current: PropTypes.instanceOf(Component) }), ]), };
quelle