Lo que quiero: obtener el ancho de desplazamiento del elemento ( <ul> ) dentro del atributo de estilo dentro de DOM
Lo que estoy intentando:
setSliderScrollWidth en useEffect debe actualizar el estado de sliderScrollWidth , el valor sliderEl.current.scrollWidth está disponible dentro de useEffect, pero aún dentro de useEffect, sliderScrollWidth es 0.
Además, no puedo obtener sliderEl.current.scrollWidth dentro del DOM, por lo que no puedo obtener el interior del DOM con useState o useRef.
const TextSlider = () => { const sliderEl = useRef(null); const [sliderScrollWidth, setSliderScrollWidth] = useState(0); useEffect(() => { setSliderScrollWidth(sliderEl.current.scrollWidth); console.log(sliderScrollWidth, sliderEl.current.scrollWidth); },[]) return( <ul ref={sliderEl} style={{ width: `${sliderEl.current.scrollWidth}`, }} > <li>Hello</li> </ul> ) } Lo que no entiendo : 1) ¿Por qué si puedo obtener sliderEl.current.scrollWidth dentro de useEffect , el valor de sliderScrollWidth sigue siendo 0? 2) ¿Por qué no puedo obtener el valor ref.current dentro del DOM?
El
setSliderScrollWidthenuseEffectdebe actualizar el estado desliderScrollWidth,the sliderEl.current.scrollWidthestá disponible dentro deuseEffect, pero aún dentro deuseEffectelsliderScrollWidthes 0.
Correcto, las actualizaciones de estado no son inmediatas . En un componente basado en ganchos, llamar al setter de estado eventualmente hará que React vuelva a llamar a la función de su componente, y cuando lo haga, la función de su componente obtendrá el valor actualizado de useState en la nueva constante creada para esa llamada.
Además, no puedo obtener
sliderEl.current.scrollWidthdentro del DOM ...
Supongo que te refieres a dónde estás tratando de usarlo en el accesorio de style . No puede hacer eso, el elemento aún no existe en el momento en que intenta usar sliderEl.current.scrollWidth , y sliderEl aún no tiene una referencia (porque no existe).
Puede configurar sliderEl.current.style.width en la devolución de llamada del efecto, porque en ese punto existirá el elemento DOM y sliderEl lo tendrá:
const TextSlider = () => { const sliderEl = useRef(null); useEffect(() => { sliderEl.current.style.width = `${sliderEl.current.scrollWidth}px`; },[]); return( <ul ref={sliderEl} > <li>Hello</li> </ul> ); }; Ese es uno de los propósitos de useEffect (o useLayoutEffect , en algunos casos): aplicar información al elemento DOM que no puede aplicar antes.
Creo que este pequeño cambio te puede ayudar.
Al final de useEffect put ,[sliderScrollWidth]
const TextSlider = () => { const sliderEl = useRef(null); const [sliderScrollWidth, setSliderScrollWidth] = useState(0); useEffect(() => { setSliderScrollWidth(sliderEl.current.scrollWidth); console.log(sliderScrollWidth, sliderEl.current.scrollWidth); },[sliderScrollWidth]) return( <ul ref={sliderEl} style={{ width: `${sliderScrollWidth}`, }} > <li>Hello</li> </ul> ) }