Estoy almacenando una referencia en mi tienda redux y uso mapStateToProps para exponer la referencia de los componentes que necesitan acceso a ella.
La referencia que se almacena se parece a:
ref={node => this.myRefToBePutInReduxGlobalStore = node}
¿Cuál es el propType correcto para esta referencia?
ref
prop es una función con el primer argumento una referencia al elemento DOM o nulo. Es una función .propType
pararefs
, pero se puede utilizar paraprops
. Dado que lo está pasando a la tienda redux, entonces se representa como un meprop
gustathis.props.myRefToBePutInReduxGlobalStore
.myRefToBePutInReduxGlobalStore
debe ser el tipo de nodo, por lo quePropTypes.node
debería funcionar para ustedPropType.object
porque ref es básicamente una instancia de clase que es un objeto. Por lo tanto, cuando pase el elemento ref como accesorios, sería de tipo de objetoRespuestas:
TL; DR
Si desea especificar un tipo de referencia que solo espera elementos DOM nativos, como a
div
o aninput
, la definición correcta es la siguiente: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) }) ])
Respuesta al problema específico descrito en la publicación original.
En el ejemplo de la pregunta OP, no es el tipo ref prop lo que debe declararse, sino las cosas señaladas por la referencia, y que se pasarán desde el uso de redux
mapStateToProps
. El tipo de prop para un elemento DOM sería:myRefToBePutInReduxGlobalStore: PropTypes.instanceOf(Element)
(si es un elemento DOM). Aunque yo haría:myElementToBePutInReduxGlobalStore
(un elemento no es una referencia)Respuesta larga a la pregunta real
P: ¿Cuál es el tipo de propiedad correcto para un árbitro en React?
Ejemplo de caso de uso:
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} /> }
Hoy en día, existen dos tipos de referencias en react:
{ current: [something] }
generalmente creado porReact.createRef()
ayudante oReact.useRef()
gancho[something]
como argumento (como la del ejemplo OP)Nota: históricamente, también podría usar una referencia de cadena, pero se considera heredada y se eliminará de reaccionar
El segundo elemento es bastante simple y requiere el siguiente tipo de accesorio:
PropTypes.func
.La primera opción es menos obvia porque es posible que desee especificar el tipo de elemento señalado por la ref.
Muchas buenas respuestas
ref
puede apuntar a algo más que al elemento DOM.Si quieres ser totalmente flexible:
refProp: PropTypes.oneOfType([ PropTypes.func, PropTypes.shape({ current: PropTypes.any }) ])
Lo anterior solo aplica la forma del objeto ref w /
current
property. Funcionará en todo momento para cualquier tipo de ref. Para el propósito de usar el tipo de apoyo, que es una forma de detectar cualquier inconsistencia cuando se desarrolla , esto probablemente sea suficiente. Parece muy poco probable que un objeto con forma{ current: [any] }
, y se pasa a unrefToForward
accesorio, no sea una referencia real.Sin embargo , es posible que desee declarar que su componente no espera ningún tipo de referencia, sino solo un cierto tipo, dado para qué necesita esa referencia.
He configurado una caja de arena que muestra algunas formas diferentes de declarar una referencia, incluso algunas no convencionales, y luego las probé con muchos tipos de accesorios. Puedes encontrarlo aquí .
Si solo espera una referencia que apunte a un elemento de entrada nativo, no a ningún HTML
Element
:refProp: PropTypes.oneOfType([ PropTypes.func, PropTypes.shape({ current: PropTypes.instanceOf(HTMLInputElement) }) ])
Si solo espera una referencia que apunte a un componente de la clase React:
refProp: PropTypes.oneOfType([ PropTypes.func, PropTypes.shape({ current: PropTypes.instanceOf(Component) }) ])
Si solo espera una referencia que apunte a un componente funcional utilizando
useImperativeHandle
para exponer algún método público:refProp: PropTypes.oneOfType([ PropTypes.func, PropTypes.shape({ current: PropTypes.object }) ])
Nota: el tipo de apoyo anterior es interesante porque también cubre los componentes react y los elementos DOM nativos, porque todos heredan el javascript base
Object
No hay una única buena manera de declarar el tipo de prop para una referencia, depende del uso. Si su referencia apunta a algo muy identificado, puede valer la pena agregar un tipo de accesorio específico. De lo contrario, basta con comprobar la forma general.
Nota sobre la representación del lado del servidor
Si su código tiene que ejecutarse en el servidor, a menos que ya tenga un entorno DOM polyfill,
Element
o cualquier otro tipo del lado del cliente estaráundefined
en NodeJS. Puede utilizar la siguiente cuña para apoyarlo:Element = typeof Element === 'undefined' ? function(){} : Element
Las siguientes páginas de React Docs brindan más información sobre cómo usar referencias, tanto object como callbacks , y también cómo usar
useRef
hookRespuesta actualizada gracias a @Rahul Sagore, @Ferenk Kamra, @svnm y @Kamuela Franco
fuente
Element
se define en la representación del lado del servidor. ¿Alguna solución a eso?Element = typeof Element === 'undefined' ? function(){} : Element
(Sugerida por Ryan Florence en algún número de github). Si funciona para usted, puedo agregarlo a mi respuesta.if (!isBrowser) { global.Element = null; }
. Trabajó para mi.isBrowser = typeof window !== 'undefined';
Muy similar a la publicación de @ Pandaiolo,
PropTypes.elementType
ahora ha sido agregadoforwardedRef: PropTypes.oneOfType([ PropTypes.func, PropTypes.shape({ current: PropTypes.elementType }) ]),
Si
PropTypes.elementType
se agregó PropTypes> = 15.7.0 el 10 de febrero de 2019 en este PRfuente
elementType
no funcionó para mí, así que probé un montón de tipos de accesorios en diferentes tipos de componentes que pueden ser señalados por un árbitro, en una caja de arena. Aquí están los resultados: codesandbox.io/s/loving-benz-w6fbh . No estoy seguro de que cubrí todas las posibilidades, pero parece que el PropType correcta para el elemento DOM esinstanceOf(Element)
(oobject
), para una clase esinstanceOf(Component)
(oobject
) y para el caso de uso específico de un componente funcional utilizandouseImperativeHandle
esobject
. PensamientosSolo verifico la forma preferida y, dado que PropType.object no es muy valioso, terminé usando esto:
PropTypes.shape({ current: PropTypes.instanceOf(Element) })
fuente
Revisé todas las respuestas anteriores, pero recibo una advertencia de la reacción, así que investigué mucho y obtuve la respuesta correcta.
import React, { Component } from 'react'; ComponentName.propTypes = { reference: PropTypes.oneOfType([ PropTypes.func, PropTypes.shape({ current: PropTypes.instanceOf(Component) }), ]), };
fuente