Tengo un ejemplo simple de un componente:
function App() { const observed = useRef(null); console.log(observed.current); return ( <div ref={observed} className="App"> <h1>Hello CodeSandbox</h1> <h2>Start editing to see some magic happen!</h2> </div> ); } const rootElement = document.getElementById("root"); ReactDOM.render(<App />, rootElement); Esperaría que observed.current . actual fuera de tipo elemento y actual no estaría vacío sino el elemento div con todas sus propiedades. Mi entendimiento sería:
Pero resulta que .current permanece vacío. Esto es malo ya que quiero pasar observado a una función que espera un argumento de tipo Elemento.
Ref.current es nulo porque la referencia no se establece hasta que la función regresa y se procesa el contenido. El gancho useEffect se activa cada vez que cambia el valor del contenido de la matriz que se le pasa. Al pasar observed en la matriz y al pasar una devolución de llamada que registra observed en la consola, el enlace useEffect se puede aprovechar para realizar su tarea.
useEffect(() => { console.log(observed.current); }, [observed]);Editar: esto solo funciona en el primer renderizado, ya que los cambios en una referencia no desencadenan re-renderizaciones. Pero la declaración general sobre useEffect aún se mantiene. Si desea observar cambios en una referencia de un elemento dom, puede usar una devolución de llamada como referencia.
<div ref={el => { console.log(el); observed.current = el; }} // or setState(el) className="App" >En el momento en que ocurre console.log , la ref aún no está configurada. Intenta poner tu console.log en un useEffect y funciona como quieres.
import React, { useRef, useEffect } from "react"; import ReactDOM from "react-dom"; import "./styles.css"; function App() { const observed = useRef(null); useEffect(() => { console.log(observed.current); }, [observed]); return ( <div ref={observed} className="App"> <h1>Hello CodeSandbox</h1> <h2>Start editing to see some magic happen!</h2> </div> ); } const rootElement = document.getElementById("root"); ReactDOM.render(<App />, rootElement);Esto es lo que terminé haciendo ya que llamar a useEffect en rlvRef no capturó todos los eventos.
const rlvRef = useRef() const [refVisible, setRefVisible] = useState(false) useEffect(() => { if (!refVisible) { return } // detected rendering }, refVisible) return ( <RecyclerListView ref={el => { rlvRef.current = el; setRefVisible(!!el); }} ... /> )