I have a list of refs that is being forwarded to the child components. They seem to work fine as I can do operations with them as feedback to the user actions (in this case, it is scrolling into view). However, I want to scroll to them when component is rendered/mounted, which sounds like a classic ref usage: add ref dependencies to a useEffect and scroll when they are ready. But it basically does not work. When I console.log out the refs, I see the ref.current is assigned. However when I console.log refs[scrollTo], it is undefined. This might be related to how chrome browser consoles work though.
So here is my example code:
const MyComponent = (props) => {
const refs = {
a: useRef<HTMLDivElement>(null),
b: useRef<HTMLDivElement>(null),
c: useRef<HTMLDivElement>(null),
}
useEffect(() => {
if (props.scrollTo && refs[props.scrollTo].current) {
refs[props.scrollTo].current.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
}, [refs.a.current, refs.b.current, refs.c.current]);
return <>
<ChildComponent key='a' ref={refs.a} onClick={
refs.a.current?.scrollIntoView({ behavior: 'smooth', block: 'start' })
} />
<ChildComponent key='b' ref={refs.b} onClick={
refs.b.current?.scrollIntoView({ behavior: 'smooth', block: 'start' })
} />
<ChildComponent key='c' ref={refs.c} onClick={
refs.c.current?.scrollIntoView({ behavior: 'smooth', block: 'start' })
} />
</>
};
refs[props.scrollTo].current always returns null here in the use effect, preventing me to scroll there on load. useCallback solution also does not apply here for me as well, since I need those DOM refs for scrollintoview behaviour on onclicks. What am I missing here? And how can I ensure the behaviour I want?
2
Answers
Incorrect Dependencies: Including references (refs.a.current, refs.b.current, etc.) in the dependencies of useEffect can lead to unexpected behaviors. refs.a.current does not change frequently, so React may not properly detect changes in the references.
props.scrollTo
needs to be a string that contains one of"a"
,"b"
, or"c"
.Also, if it is initialised as something else (possibly
null
in your case), with its value being set in an effect, then you need to addprops.scrollTo
to your dependency array.