I have often encountered situations where a user needs to jump to a specific section of a page.
Whether it is a complex dashboard or a long landing page, providing a “scroll to” feature significantly improves the user experience.
In this tutorial, I will show you exactly how to handle scrolling to a component in React using various methods I’ve used in production environments.
The Power of useRef for Targeted Scrolling
When I first started with React, I realized that the “standard” way of using id anchors often felt clunky in a single-page application (SPA).
Using the useRef hook is the most reliable way to reference a specific DOM element without causing unnecessary re-renders.
Imagine you are building a real estate platform for New York City apartments. You want a button at the top that scrolls directly to the “Neighborhood Amenities” section.
Here is the full code to achieve this:
import React, { useRef } from 'react';
const RealEstateApp = () => {
// Create a reference for the target section
const amenitiesRef = useRef(null);
const scrollToSection = () => {
// Check if the ref is attached to the element
if (amenitiesRef.current) {
amenitiesRef.current.scrollIntoView({
behavior: 'smooth',
block: 'start',
});
}
};
return (
<div style={{ fontFamily: 'Arial, sans-serif', padding: '20px' }}>
<header style={{ position: 'sticky', top: 0, background: '#fff', padding: '10px', borderBottom: '1px solid #ccc' }}>
<h1>NYC Luxury Living</h1>
<button
onClick={scrollToSection}
style={{ padding: '10px 20px', backgroundColor: '#007bff', color: 'white', border: 'none', cursor: 'pointer' }}
>
View Neighborhood Amenities
</button>
</header>
<section style={{ height: '800px', backgroundColor: '#f9f9f9', padding: '20px' }}>
<h2>Apartment Overview</h2>
<p>Explore our beautiful listings in the Upper East Side.</p>
</section>
{/* This is our target component */}
<section
ref={amenitiesRef}
style={{ height: '800px', backgroundColor: '#e9ecef', padding: '20px' }}
>
<h2>Neighborhood Amenities</h2>
<ul>
<li>Central Park - 5 min walk</li>
<li>Metropolitan Museum of Art - 10 min walk</li>
<li>Lexington Ave Subway - 2 blocks away</li>
<li>Whole Foods Market - nearby</li>
</ul>
</section>
</div>
);
};
export default RealEstateApp;You can see the output in the screenshot below.

In this example, scrollIntoView is the star of the show. It is a native Web API that works beautifully within the React lifecycle.
Implement Smooth Scrolling with window.scrollTo
Sometimes, you need more control over the exact pixel position, especially if you have a sticky header that might overlap your content.
In my experience, calculating the offset manually using window.scrollTo is the best way to handle fixed navigation bars.
Let’s look at a scenario involving a US-based Financial Services landing page where we need to scroll to a “Tax Calculator” section.
import React, { useRef } from 'react';
const FinancePortal = () => {
const calculatorRef = useRef(null);
const handleScroll = () => {
if (calculatorRef.current) {
// Calculate the distance from the top of the page
const topOffset = calculatorRef.current.offsetTop;
// Subtract the height of a sticky header (e.g., 80px)
window.scrollTo({
top: topOffset - 80,
behavior: 'smooth'
});
}
};
return (
<div>
<nav style={{
height: '80px',
position: 'fixed',
top: 0,
width: '100%',
backgroundColor: '#1a1a1a',
color: 'white',
display: 'flex',
alignItems: 'center',
padding: '0 20px',
zIndex: 1000
}}>
<button onClick={handleScroll} style={{ cursor: 'pointer' }}>
Go to IRS Tax Calculator
</button>
</nav>
<div style={{ marginTop: '100px', padding: '20px' }}>
<div style={{ height: '1000px', background: '#f4f4f4' }}>
<h2>Investment Insights 2024</h2>
<p>Market trends for the S&P 500 and tech stocks.</p>
</div>
<div ref={calculatorRef} style={{ height: '600px', background: '#ffffff', border: '2px solid #28a745', padding: '20px' }}>
<h2>Federal Tax Calculator</h2>
<p>Estimate your 2024 tax liability based on US tax brackets.</p>
<input type="number" placeholder="Annual Income" style={{ padding: '10px', width: '250px' }} />
</div>
</div>
</div>
);
};
export default FinancePortal;You can see the output in the screenshot below.

Using offsetTop allows you to subtract the height of your navigation bar so the title isn’t hidden behind the header.
Scroll to Components Across Different Files
In large-scale React apps, your “Trigger” button and your “Target” component are rarely in the same file.
I usually solve this using a shared Ref or by passing the Ref down through props.
Suppose we are building a National Park travel guide. We have a Navigation component and a ParkDetails component.
App.js (Parent Component)
import React, { useRef } from 'react';
import Navigation from './Navigation';
import ParkDetails from './ParkDetails';
const NationalParksApp = () => {
const yellowstoneRef = useRef(null);
return (
<div>
<Navigation targetRef={yellowstoneRef} />
<div style={{ height: '100vh' }}>
<h1>Explore America's Parks</h1>
</div>
<ParkDetails ref={yellowstoneRef} />
<div style={{ height: '100vh' }} />
</div>
);
};
export default NationalParksApp;Navigation.jsx
import React from 'react';
const Navigation = ({ targetRef }) => {
const scroll = () => {
targetRef.current?.scrollIntoView({ behavior: 'smooth' });
};
return (
<nav style={{ background: '#2d4739', color: 'white', padding: '15px' }}>
<button onClick={scroll}>Jump to Yellowstone National Park</button>
</nav>
);
};
export default Navigation;ParkDetails.jsx
import React, { forwardRef } from 'react';
const ParkDetails = forwardRef((props, ref) => {
return (
<div ref={ref} style={{ padding: '50px', backgroundColor: '#fdf5e6' }}>
<h2>Yellowstone National Park (Wyoming/Montana)</h2>
<p>Home to the famous Old Faithful geyser and diverse wildlife.</p>
</div>
);
});
export default ParkDetails;By using forwardRef, we allow the parent component to “reach into” the child component and attach a reference to a specific DOM node.
Handle “Scroll to Top” for Long Content
Many professional sites include a “Back to Top” button that appears once the user has scrolled down.
I have implemented this hundreds of times. It usually requires an event listener to track the scroll position.
Here is a clean implementation for a US Tech News blog:
import React, { useState, useEffect } from 'react';
const TechBlog = () => {
const [isVisible, setIsVisible] = useState(false);
// Toggle visibility of button based on scroll position
useEffect(() => {
const toggleVisibility = () => {
if (window.pageYOffset > 300) {
setIsVisible(true);
} else {
setIsVisible(false);
}
};
window.addEventListener('scroll', toggleVisibility);
return () => window.removeEventListener('scroll', toggleVisibility);
}, []);
const scrollToTop = () => {
window.scrollTo({
top: 0,
behavior: 'smooth',
});
};
return (
<div style={{ padding: '20px', lineHeight: '1.6' }}>
<h1>Silicon Valley Weekly</h1>
<div style={{ height: '2000px' }}>
<p>Latest updates on AI, Cloud Computing, and Venture Capital.</p>
{/* Lots of content here */}
</div>
{isVisible && (
<button
onClick={scrollToTop}
style={{
position: 'fixed',
bottom: '40px',
right: '40px',
padding: '15px',
borderRadius: '50%',
backgroundColor: '#333',
color: '#fff',
cursor: 'pointer',
border: 'none'
}}
>
↑ Top
</button>
)}
</div>
);
};
export default TechBlog;This pattern ensures that the button only appears when the user actually needs it.
Common Issues and Best Practices
One mistake I often see junior developers make is trying to scroll before the component has actually mounted.
Always ensure you check if ref.current exists before calling a scroll method.
Also, remember that scrollIntoView may not work perfectly in very old versions of Safari.
If you are supporting legacy browsers for a large US enterprise client, you might want to use a polyfill for smooth scrolling.
Another tip: use the block: ‘center’ option if you want the target component to land in the middle of the screen instead of the top.
In this guide, I have covered the most practical ways to handle scrolling to a component in React.
Whether you choose useRef with scrollIntoView or manual calculations with window.scrollTo, the key is to prioritize a smooth user experience.
You may also read:
- 5 Best React Table Components in 2026
- Prop Distribution in React Functional Components
- React Google Calendar Component
- How to Return a Component from a React Hook

I am Bijay Kumar, a Microsoft MVP in SharePoint. Apart from SharePoint, I started working on Python, Machine learning, and artificial intelligence for the last 5 years. During this time I got expertise in various Python libraries also like Tkinter, Pandas, NumPy, Turtle, Django, Matplotlib, Tensorflow, Scipy, Scikit-Learn, etc… for various clients in the United States, Canada, the United Kingdom, Australia, New Zealand, etc. Check out my profile.