skip to Main Content

Ok, I am trying to create a dropdown and when selecting an item, the page should scroll to a specific section (ref).

I have several divs with the same ref (as I have more than 30 divs that require a ref).

const SettingView = () => {
    const selectedItem = "el2"; // This is temporarily as it will be the item from a dropdown
    const ref = useRef<HTMLDivElement[]>([]);
    const filterRef = (el: HTMLDivElement) => ref.current.push(el);

    return (
        <>
            <div ref={filterRef} id="el1">Some Text</div>
            <div ref={filterRef} id="el2">Some Text2</div>
            <div ref={filterRef} id="el3">Some Text3</div>
            <div ref={filterRef} id="el4">Some Text4</div>
            ....
        </>
    )
}

export default SettingView;

So on a button click it should find the div ref that has the id from the selectedItem and scroll to it.

How would I do that?

2

Answers


  1. You can achieve this by using the scrollIntoView() method on the selected element’s ref. Here’s how you can modify your SettingView component to achieve this functionality:

    import React, { useRef } from 'react';
    
    const SettingView = () => {
        const selectedItem = "el2";
        const ref = useRef<HTMLDivElement[]>([]);
        const filterRef = (el: HTMLDivElement) => ref.current.push(el);
    
        const scrollToRef = (ref: React.RefObject<HTMLDivElement>, id: string) => {
            const selectedRef = ref.current.find(item => item.id === id);
            if (selectedRef) {
                selectedRef.scrollIntoView({ behavior: 'smooth', block: 'start' });
            }
        };
    
        React.useEffect(() => {
            scrollToRef(ref, selectedItem);
        }, [selectedItem]);
    
        return (
            <>
                <div ref={filterRef} id="el1">Some Text</div>
                <div ref={filterRef} id="el2">Some Text2</div>
                <div ref={filterRef} id="el3">Some Text3</div>
                <div ref={filterRef} id="el4">Some Text4</div>
            </>
        );
    }
    
    export default SettingView;
    

    In this code:
    scrollToRef function takes the ref array and the id of the selected item. It finds the ref with the matching id and scrolls it into view using scrollIntoView() with options for smooth behavior and starting from the block’s start.
    useEffect hook is used to trigger the scrolling effect whenever selectedItem changes.

    Login or Signup to reply.
  2. If you render your buttons using a map(), which should be fine since only the id differs, then you can use the iterator of map to use that as an id.

    Then when clicking the button, get that index in the ref.current array and call (eg) scrollIntoView() on that.


    Example:

    • Click on a button to call scrollIntoView on that
    • Click on the uppermost (real) button to call scrollIntoView on index 50
    const { useState, useRef } = React;
    
    const SettingView = () => {
    
        const ref = useRef([]);
        
        const onButtonClick = (i) => {
            console.info('Clicked on ', i);
            if (ref.current[i]) {
                ref.current[i].scrollIntoView();
            }
        }
        
        return (
          <React.Fragment>
            <button onClick={() => onButtonClick(50)}>Scroll to Button #50</button>
            {[...Array(100)].map((e, i) => (
                <div 
                    onClick={() => onButtonClick(i)}
                    ref={el => ref.current[i] = el} 
                    id={"el" + i}
                >Button {i}</div>
            ))}
          </React.Fragment>
         );
    }
    
    ReactDOM.render(<SettingView />, document.getElementById("react"));
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
    <div id="react"></div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search