How to get the react useRef() ‘s value of the section inside SliceZone

Hello,
I want to create a tab bar similar to this sandbox example.

I have two components: the <Tabs/> and another one which is actually a <SliceZone />. When scrolling through the text section, the corresponding tab should be marked as active. Conversely, when a tab is clicked, the text section should scroll into the viewport.

To achieve this, I am using useRef() to get references to the <section> elements inside SliceZone , so I can determine if a section element is visible in the viewport.

I created a common parent component for the two parts (Tabs and Texts).

Parent comp:

'use client';
import ....

type ParentProps={
   ...
}
export default function Parent (){
       const sectionRefs = useRef<(HTMLElement | null)[]>([]);
       function handleClick(index: number) {
        /* ...when click at the tab, corresponding text will be displayed,
         then `setActiveIndex(index)`
        */
       }

       useEffect(()=>{
       ...
       // call IntersectionObserver()
       // if the section is detected as visible, then setActiveIndex() to the index of entry  
   },[])

    return <>
     <Tabs handleClick={...} activeIndex={...} />
     /*Texts*/
     <SliceZone slices={...} 
         components={...} 
         context={{sectionRefs:sectionRefs}} />
    </>
}
export type PageProps = SliceComponentProps<Content.CvSlice>;
export type AllProps = CvProps & {
  context:{sectionRefs: MutableRefObject<(HTMLElement | null)[]>}
}

const Page = (({ slice, context, index }:AllProps):JSX.Element =>{
    return (<section
      ...
      ref={(el: HTMLElement | null) =>
        (context.sectionRefs.current[index] = el)}
      >      
      {slice.variation==="text1" && 
      <article>
       ...
      </article>
      }

      {slice.variation==="text2" 
       <article >
       ...
       </article>
       }


     {slice.variation==="text3"&&
      <article>
      ...
      </article>
     }
    </section>
  );
});

export default Page;

Could someone provide some guidance on how to resolve this issue?
Thank you!

-----edit ------
I got the ref inside <SliceZone /> by passing context={ref} and created a callback function inside <SliceZone />. The code has been corrected in this version.

This is a react question not prismic - however I think you need to look at forwardRefs to read the refs in the child components - but it's 2024 so honestly drop your code into chat gtp ask it how you can achieve it and it will do a pretty damn good job of fixing it. That $USD20 pm pays for itself pretty quickly esp if your debugging someone else's spaghetti code.

Hello,
Thanks for the direction.
Honestly, I use ChatGPT for a lot of things—it's helpful, but not a miracle. If the structure isn't open source, the AI won't be of much help. And I don't think it's the purpose of building a forum, either.

Hello again,
I can answer the question by myself now...

How to get the ref inside sliceZone :

The Parent Comp :

export default Parent(...props){
   const sectionRefs = useRef(null);
   ...
   return <SliceZone slices={...} 
          components={...} 
          context={{sectionRefs:sectionRefs}} 
          />
}

Slice index.tsx

export type PageProps = SliceComponentProps<Content.PageSlice>;
//extend the props
export type AllProps = PageProps & {
  context:{sectionRefs: MutableRefObject<(HTMLElement | null)[]>}
}

const Page = (({ slice, context, index }:AllProps):JSX.Element =>{
   return <section
       data-slice-type={...}
      data-slice-variation={...}
      ref={(el: HTMLElement | null) =>
        {context.sectionRefs.current[index] = el;
        { /*check if you get the right index and section element */}
        console.log(`Ref assigned for index ${index}:`, el); 
        }
>...</section>
}

The SliceZone is rendered asynchronously, so when referring to the ref inside the useEffect() function, a setTimeout() function should be implemented.

useEffect(()=>{
      function ObserverCallback(entries: IntersectionObserverEntry[]) {
       ...
      }
      const options = {
       ...
      }
  
      const observer = new IntersectionObserver(
        ObserverCallback, options
      );

      const timer = setTimeout(() => {
        sectionRefs.current.forEach((ref) => {
          if (ref) {
            observer.observe(ref);
          }
        });
      }, 100); 

      return ()=>{
        ... //unmount function
      }
    },[])
    console.log(activeIndex)

Hope this will help those who encounter the same problem.