What I want: to get element(<ul>
) scrollwidth inside of the style attribute inside DOM
What I am trying:
The setSliderScrollWidth
in useEffect
should update the state for sliderScrollWidth
, the sliderEl.current.scrollWidth
value is avaiable inside of the useEffect, but still inside of useEffect the sliderScrollWidth
is 0.
Also I can not get sliderEl.current.scrollWidth
inside of the DOM, so I am unable to get the inside of DOM with either useState or 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>
)
}
What I don't understand: 1) Why if I can get sliderEl.current.scrollWidth
inside of useEffect
the sliderScrollWidth
value is still 0? 2) Why can't I get the ref.current value inside the DOM?
CodePudding user response:
The
setSliderScrollWidth
inuseEffect
should update the state forsliderScrollWidth
,the sliderEl.current.scrollWidth
value is avaiable inside of theuseEffect
, but still inside ofuseEffect
thesliderScrollWidth
is 0.
Right, state updates are not immediate. In a hooks-based component, calling the state setter will eventually make React call your component function again, and when it does your component function will get the updated value from useState
into the new constant created for that call.
Also I can not get
sliderEl.current.scrollWidth
inside of the DOM...
I assume you're referring to where you're trying to use it on the style
prop. You can't do that, the element doesn't exist yet as of where you're trying to use sliderEl.current.scrollWidth
, and sliderEl
doesn't have a reference to it yet (because it doesn't exist).
You can set sliderEl.current.style.width
in the effect callback, because at that point the DOM element will exist and sliderEl
will have it:
const TextSlider = () => {
const sliderEl = useRef(null);
useEffect(() => {
sliderEl.current.style.width = `${sliderEl.current.scrollWidth}px`;
},[]);
return(
<ul
ref={sliderEl}
>
<li>Hello</li>
</ul>
);
};
That's one of the purpose of useEffect
(or useLayoutEffect
, in some cases): To apply information to the DOM element you can't apply earlier.
CodePudding user response:
I think this little change can help you
In the end of 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>
)
}