In traditional web page development, developers would use anchor tags and id to navigate to a certain part of a web page. While you can still add this approach to a component-based React application, you may need more code to have certain effects such as smoothly scrolling to the target point on the page. But there is a much better way to do this in React.
Table of Contents
React refs and useRef hook.
React refs is a way to access different elements(DOM nodes) of the page by creating a reference point. I this post,I will show you how to smoothly scroll to a certain point on a single page app with useRef hook.
Step 1: create a React App
Create a React app with create-react-app
Erase the default App.js code and replace it with the following code.
import React from 'react';
import './App.css';
export default function App() {
return (
<div>
<ul className='main-menu'>
<div>HOME</div>
<div>ABOUT</div>
<div>CONTACT</div>
</ul>
<Home/>
<About/>
<Contact/>
</div>
)
}
const Home = () => (
<div className="home"></div>
)
const About = () => (
<div className="about"></div>
)
const Contact = () => (
<div className="contact"></div>
)
Note that there are three components in this app.
What we are going to do is to make reference points to these components and smoothly scroll when the user clicks on the main menu on the header.
Add CSS code below to the App.css file
.main-menu{
display: inline-flex;
}
.main-menu > div {
margin: 5px;
cursor: pointer;
}
.home,.about,.contact{
height:800px;
}
.home{
background-color: rgb(221, 148, 148);
}
.about{
background-color: rgb(172, 206, 145);
}
Step 2: Creating references
Now that we have done creating the skeleton of the app, it is time to add refs. Before, the React hooks are introduced refs are created by calling React.createRef(). However, now, you can use react hook useRef() to create ref objects.
Add the following code to App.js. Note that you need to import useRef hook from ‘react’.
import React, { useRef } from 'react'
import './App.css';
function App() {
const homeOnClickRef = useRef(null);
const aboutOnClickRef = useRef(null);
const contactOnClickRef = useRef(null);
return (
<div>
<ul className='main-menu'>
<div>HOME</div>
<div>ABOUT</div>
<div>CONTACT</div>
</ul>
<Home/>
<About/>
<Contact/>
</div>
)
Ref object has a property named current. We are going to use this property to use the scrollIntoView() method of this property.
You can learn about scrollIntoView() method here
Now, we need to create a function called scrollEffect(). It takes ref object as a parameter.
const scrollEffect = ( targetRef ) =>{
targetRef.current.scrollIntoView({
behavior: 'smooth',
block: 'start',
});
}
Step 3: Adding events
We are going to initiate the scroll effect when we click on the menu items in the header. So we need trigger scrollEffect() function on onClick event.
<ul className='main-menu'>
<div onClick = { () =>scrollEffect(homeOnClickRef) }>HOME</div>
<div onClick = { ()=>scrollEffect(aboutOnClickRef) }>ABOUT</div>
<div onClick = { () =>scrollEffect(contactOnClickRef) }>CONTACT</div>
</ul>
Step 4: Passing ref object with ref attribute
ref is an attribute you need to use to passe ref objects to other components. So, add the ref attribute to components called in the App.js and assigned your custom ref objects as below.
...........
<Home ref = { homeOnClickRef }/>
<About ref = { aboutOnClickRef }/>
<Contact ref = { contactOnClickRef } />
...........
Step 5. Modify Components
Now, we need to change to code of the components. I will show you how to do to the Contact component.
First, we need to add a second argument(myref) to reference the ref object passing from the App.js.
const Contact =({},myref) => (
<div ref={ myref }className="contact"></div>
)
Or
const Contact =(props,myref) => (
<div ref={ myref }className="contact"></div>
)
Then you need to wrap the component in React.forwardRef(), which is necessary when you pass ref to child components.
const Contact = React.forwardRef(({},myref) => (
<div ref={ myref }className="contact"></div>
))
Now, you can do the same for the other two components.
A little challenge…
If you carefully watch the video below, you will notice there is a green color round button with an upward arrow in the bottom-right corner.
Your challenge is to make that button work so that when the user clicks on the button, he will go back to the home page(section). It is up to you to add any content you want for each component.
Hope you enjoy it…!