React use ref to scroll to a specific component when click on link

3.6k views Asked by At

I would like to know how to use React refs to navigate to a specific component

 function App() {
      const CompetencesRef = React.useRef();
      const ExperiencesRef = React.useRef();
      const FormationRef = React.useRef();
      const RecoRef = React.useRef();
    
    
      return (
        <ParallaxProvider>
          <ThemeProvider theme={theme}>
            <div className="App">
    
              <div className="hero">
                <HeaderApp />
                <ApprochApp />
              </div>
              <Apropos />
              <Competences parentRef={CompetencesRef} />
              <Experiences parentRef={ExperiencesRef} />
              <Formation parentRef={FormationRef} />
              <Recom parentRef={RecoRef} />
              <Contact />
              <Footer />
    
            </div >
          </ThemeProvider>
        </ParallaxProvider>
      );
    }

AppHeader

 const AppHeader = () => {
        return (
            <div >
                <Headroom>
                    <MenuApp />
                </Headroom>
    
            </div>
        )
}


   export default AppHeader

AppMenu

   const MenuApp = () => {
        return (
            <div className="menu sticky-inner grid-container">
                <div className="desktop-menu">
                    <div className="menu-item a-propos">
                        <p className='button'>Me découvrir</p>
                    </div>
                    <div className="menu-item competences">
                        <p className='button'>Compétences </p>
                    </div>
                    <div className="menu-item experiences">
                        <p className='button'>Experiences</p>
                    </div>
                    <div className="menu-item formation">
                        <p className='button'>Formation </p>
                    </div>
                </div>
                <p className="mobile-menu">
                    <MenuIcon />
                </p>
                <div className="github-ico">
                    <GitHubIcon />
                </div>
                <div className="linkedin-ico">
                    <LinkedInIcon />
                </div>
                <div className="contact">
                    <div className='contact-btn'>
                        <span className="contact-ico"> <MessageIcon /></span>  <span style={isBrowser ? { display: 'block' } : { display: 'none' }} > contact </span>
                    </div>
                </div>
            </div>
        )
    }
    export default MenuApp

I have understood that I should declare ref on the parent component, but I'm stuck on how to pass references to the menu app and make the link between it and components.

Actually, I would not use packages like react-scroll

2

There are 2 answers

2
Kalhan.Toress On

I think you need forwarding-refs

in the parent

const RecoRef = React.useRef();
....
<ChildComponent ref={RecoRef} />

in the child component

//export the component with React.forwardRefs

const ChildComponent = (props, ref) => {
    return (
        <div ref={ref}>
        .....
        </div>
    )
}

export default React.forwardRefs(ChildComponent)
0
Mechanic On

Two things are needed: a ref and scrollIntoView. this snippent is simplified version of sharing a ref between component, there is redDiv and a button in the header that scrolls into that div; I'd created the ref in the top parent element, then passed it as props to both header and the component I wanted to scroll into; in the header there is a button that calls scrollIntoView method on that ref and thus browser will scroll that element into view;

const AppHeader = (props) => {
    return (
        <div className="menu sticky-inner grid-container">
            my logo
            <button onClick={()=> props.iconMenuRefs[0].current.scrollIntoView({behavior: "smooth"})}
            > scroll to red div </button>
            <button onClick={()=> props.iconMenuRefs[1].current.scrollIntoView({behavior: "smooth"})}
            > scroll to blue div </button>
        </div>
    )
}

function App() {
  const redDivRef = React.useRef();
  const blueDivRef = React.useRef();
  return (
    <div>
      <AppHeader iconMenuRefs={[redDivRef, blueDivRef]}/>
      <br /><br /><br /><br /><br /><br /><br />
      <br /><br /><br /><br /><br /><br /><br />
      <br /><br /><br /><br /><br /><br /><br />
      <br /><br /><br /><br /><br /><br /><br />
      <br /><br /><br /><br /><br /><br /><br />
      <br /><br /><br /><br /><br /><br /><br />
      <br /><br /><br /><br /><br /><br /><br />
      <SimpleComp ref={redDivRef} color="red"/>
      <br /><br /><br /><br /><br /><br /><br />
      <br /><br /><br /><br /><br /><br /><br />
      <br /><br /><br /><br /><br /><br /><br />
      <br /><br /><br /><br /><br /><br /><br />
      <br /><br /><br /><br /><br /><br /><br />
      <br /><br /><br /><br /><br /><br /><br />
      <br /><br /><br /><br /><br /><br /><br />
      <SimpleComp ref={blueDivRef} color="blue"/>
    </div>
  );
}

const SimpleComp = React.forwardRef((props, ref) => {
  return <div style={{backgroundColor: props.color}} ref={ref}>scroll to me!</div>
})

ReactDOM.render( <App />, myApp )
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.10.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.10.0/umd/react-dom.production.min.js"></script>
<div id="myApp"></div>