I am struggling to find information about how to make React app scroll to a specific element on a newly rendered page after clicking a corresponding element. I have a homepage with 6 service cards. I also have a services page that includes more detailed descriptions about each service. I want the browser to automatically scroll to a corresponding service in the services page after a card in homepage was clicked.
Here is the Card component in the homepage:
const navigate = useNavigate()
return (
<div id={data.id} className="serviceCard slideUpContainer" onClick={() => navigate(data.link)}>
<img src={require('../visuals/' + data.img + '.png')} alt={data.title} />
<div className="slideUpContent">
<h2 className="slideUpTitle">{data.title}</h2>
<p className="slideUpText">{data.excerpt}</p>
<div className="linkContainer">
<a href={data.link}>{data.btn}<i className="glyphicon glyphicon-menu-right"></i></a>
</div>
</div>
</div>
)
}
export default ServiceCard
And here is the Service component in the services page:
return (
<div id={data.id} className={data.className}>
<div id="imgBox">
<img src={require('../visuals/services/' + data.blockImg + '.png')}
alt={data.alt} />
</div>
<div id="textBox">
<h2>{data.title}</h2>
<p>{data.description}</p>
<div>
<h3>{data.listName}</h3>
<ul>
{data.listItems.map(item =>
<ServiceListItem key={nanoid()} data={item} />
)}
</ul>
</div>
</div>
</div>
)
}
For now I was using navigate()
, I also tried adding /#ElementID
to the url and neither of those gives me the desired result. I was trying to find more info on the internet, but all I get is the scrolling option on the same page (which is easy).
Newly rendered page means that you can use an empty dependencies 'useEffect' as a callback for when the component you want into view finishes rendering and is available in the DOM:
useEffect(() => {
document.getElementById("ElementID").scrollIntoView();
// or, use a ref and
elementRef.current.scrollIntoView()
}, [])
You can also use on any parent component of the component you want into view, as parent's 'onEffect' is always called after a child has completely rendered (and its own 'onEffect' has already ran).
To complement this, you can also use in your CSS: