Estaba revisando la documentación de los ganchos cuando me encontré con useRef
.
Mirando su ejemplo ...
function TextInputWithFocusButton() {
const inputEl = useRef(null);
const onButtonClick = () => {
// `current` points to the mounted text input element
inputEl.current.focus();
};
return (
<>
<input ref={inputEl} type="text" />
<button onClick={onButtonClick}>Focus the input</button>
</>
);
}
… Parece que useRef
se puede reemplazar con createRef
.
function TextInputWithFocusButton() {
const inputRef = createRef(); // what's the diff?
const onButtonClick = () => {
// `current` points to the mounted text input element
inputRef.current.focus();
};
return (
<>
<input ref={inputRef} type="text" />
<button onClick={onButtonClick}>Focus the input</button>
</>
);
}
¿Por qué necesito un gancho para árbitros? ¿Por qué useRef
existe?
fuente
useRef
, publicado por uno de los desarrolladores de React. No es lo mismo que simplemente llamarcreateRef
, yacreateRef
que no es un gancho y no persiste ningún estado entre llamadas. La respuesta de Ryan Cogswell también tiene un buen ejemplo de las diferencias.tldr
A
ref
es un objeto JS simple{ current: <some value> }
.React.createRef()
es una fábrica que devuelve un árbitro{ current: null }
, sin magia involucrada .
Es suficiente usaruseRef(initValue)
también devuelve una referencia{ current: initValue }
similar aReact.createRef()
. Además , memoriza esta referencia para que sea persistente en múltiples representaciones en un componente de función .React.createRef
en componentes de clase, ya que el objeto ref se asigna a una variable de instancia , por lo tanto, accesible en todo el componente y su ciclo de vida:this.myRef = React.createRef(); // stores ref in "mutable" this context (class)
useRef(null)
básicamente es equivalente auseState(React.createRef())[0]
1 .1 Reemplazar
useRef
conuseState
+createRef
El siguiente tweet ha sido esclarecedor para mí:
Con los conocimientos de la
tldr
sección, ahora podemos concluir más:El código anterior "abusa"
useState
para conservar la referencia devueltaReact.createRef()
.[0]
simplemente selecciona la parte del valor deuseState
-[1]
sería el definidor.useState
provoca una repetición en contraste conuseRef
. Más formalmente, React compara la referencia del objeto nuevo y antiguo parauseState
, cuando se establece un nuevo valor a través de su método de establecimiento. Si mutamos el estado deuseState
directamente (opuesto a la invocación del establecedor), su comportamiento se vuelve más o menos equivalente auseRef
, ya que ya no se activa ninguna repetición:// Example of mutaing object contained in useState directly const [ref] = useState({ current: null }) ref.current = 42; // doesn't cause re-render
Nota: ¡No hagas esto! Utilice la
useRef
API optimizada en lugar de reinventar la rueda. Lo anterior es para fines ilustrativos.fuente
Solo para resaltar un propósito:
createRef
es tan simple comoreturn {current: null}
. Es una forma de manejarref=
prop de la manera más moderna y eso es todo (mientras que la función de cadena es demasiado mágica y la devolución de llamada parece demasiado detallada).useRef
mantiene algunos datos antes del renderizado y cambiarlos no provoca que se vuelva a renderizar (como louseState
hace). Rara vez están relacionados. Todo lo que espera para el componente basado en clases va a los campos de instancia (this.* =
) parece candidato para ser implementadouseRef
en componentes funcionales.Say
useCallback
funciona como métodos de clase acotada (this.handleClick = .....bind(this)
) y puede volver a implementarse (pero no deberíamos reinventar la rueda con seguridad)useRef
.Otros ejemplos son las referencias DOM, los ID de tiempo de espera / intervalo, los identificadores o referencias de cualquier biblioteca de terceros.
PD: Creo que el equipo de React eligió un nombre diferente para
useRef
evitar confusionescreateRef
. QuizásuseAndKeep
o inclusousePermanent
.fuente
Sin embargo, otra adición importante a las respuestas de otros.
No puede establecer un nuevo valor para
createRef
. Pero puedes poruseRef
.const ur = useRef(); const cr = createRef(); ur.current = 10; // you can do it, and value is set cr.current = 10; // you can, but it's no good, it will not change it
fuente
current
propiedad como de costumbre (solo lo probé). No importa si la referencia se crea medianteuseRef
ocreateRef
.