Reputation: 1408
I am struggling to scroll the node into view only on initial render. Here is what I am trying to do.
const [lastItemRef, setLastItemRef] = useState(null);
const [isScrolled, setIsScrolled] = useState(false);
useEffect(() => {
if (lastItemRef !== null && !isScrolled) {
lastItemRef.scrollIntoView({
block: 'end',
inline: 'center',
});
setIsScrolled(true);
}
}, [lastItemRef, isScrolled]);
[![return (
<SomeList>
<DeepItem ref={lastItemRef} />
</SomeList>
)][1]][1]
** Check the screens **
DeepItem
is is mentioned in the screen and I need to scroll into its view only once on the initial render.The strange thing is that when I remove setIsScrolled(true);
the scrollIntoView
is working but also is working on subseqent renders when I am trying to scroll the list up and down or left and right.
As I can somehow imagine DOM interaction is not happenning because it's waiting for the react to update the internal state and once it happens, isScrolled
is already false
.
In the second screen you can see the result without removing setIsScrolled(true)
.
F.Y.I. - I am using MUI Table with react-window FixedSizeList
.
Upvotes: 2
Views: 1287
Reputation: 15520
You don't need to have state isScrolled
to handle that case. Instead of that, you can call useEffect
with []
(no dependencies) that will trigger your logic only once after the first rendering.
useEffect(() => {
if (lastItemRef !== null) {
lastItemRef.scrollIntoView({
block: 'end',
inline: 'center',
});
}
}, []);
If lastItemRef
is null initially, you can add it to the dependency list. It's always referred to the same object, so useEffect
also triggers once after lastItemRef
has a value.
useEffect(() => {
if (lastItemRef !== null) {
lastItemRef.scrollIntoView({
block: 'end',
inline: 'center',
});
}
}, [lastItemRef]);
Upvotes: 3