Estoy usando ResizeObserver para llamar a una función cuando se cambia el tamaño de la pantalla, pero necesito obtener el valor actualizado de un estado dentro del observador para determinar algunas condiciones antes de que se invoque la función.
Es algo como esto:
let [test, setTest] = React.useState(true) const callFunction = () => { console.log('function invoked') setTest(false) // => set 'test' to 'false', so 'callFunction' can't be invoked again by the observer } const observer = React.useRef( new ResizeObserver(entries => { console.log(test) // => It always has the initial value (true), so the function is always invoked if (test === true) { callFunction() } }) ) React.useEffect(() => { const body = document.getElementsByTagName('BODY')[0] observer.current.observe(body) return () => observer.unobserve(body) }, [])No se preocupe por los detalles o por qué estoy haciendo esto, ya que mi aplicación es mucho más compleja que este ejemplo.
Solo necesito saber si hay alguna forma de obtener el valor actualizado dentro del observador. Ya he pasado un tiempo considerable tratando de resolver esto, pero aún no pude.
¿Alguna idea?
El problema es que está definiendo un nuevo observador en cada representación del componente. Moverlo dentro de useEffect resolverá el problema. también debe cambiar este observer.unobserve(body) a este observer..current.unobserve(body) .
He creado este codesandbox para mostrarte cómo hacerlo correctamente. de esta manera, no necesita una variable externa y puede usar los estados de manera segura.
import { useEffect, useState, useRef } from "react"; const MyComponent = () => { const [state, setState] = useState(false); const observer = useRef(null); useEffect(() => { observer.current = new ResizeObserver((entries) => { console.log(state); }); const body = document.getElementsByTagName("BODY")[0]; observer.current.observe(body); return () => observer.current.unobserve(body); }); return ( <div> <button onClick={() => setState(true)}>Click Me</button> <div>{state.toString()}</div> </div> ); }; export default MyComponent;