Scroll a React component into view
- Published
React has an easy way to access DOM APIs of HTML elements through references. We learn how React exposes HTML elements by scrolling an element into view on the click of a button.
People's behavior on websites did not change very much since the early days of the internet. But one thing that did change - since 1994 to be more precise - was that we learned to scroll longer pages of content. We are now used to websites where not all information may be visible at first sight.
But how do we grab a user's attention for something that isn't visible in the current part of the viewport it's currently looking at. We can utilize a very handy browser API for that, called Element.scrollIntoView(). Which does exactly what it says it does with a few nice options to modify its behavior.
Scroll to element with plain HTML
Before diving into the React implementation, let's try out the API on a simple HTML list with vanilla JavaScript.
Let's say we have an article with a long text.
html
Whenever a user reached the end of the article, we would like to provide a button to scroll back to the top of the article. This can be achieved by adding a link with the id of the <h1> heading element on the end of the paragraph.
html
Now when the user clicks the link, the browser will automatically jump back to the title element and the user is back on the top of the article. This is the basic way to scroll an element into view without using any JavaScript at all.
Scroll to element with vanilla JavaScript
To scroll to the element with JavaScript, you can create a button which scrolls back the the top when a user clicks it.
html
By using an event listener on the button, whenever it is invoked we get the heading element by its title identifier and tell it to scroll into the browser's viewport.
For most use cases, this is sufficient. But sometimes you'll would like to have a nice animation while scrolling. Luckily you can pass additional options to the method to do exactly that.
js
By setting the behavior option to smooth, the browser will gently scroll to the element instead of the instant jump.
Scroll to a React element
Now the next step is to figure out how we can apply this smooth scrolling behavior on a React component. We can still use the Element.scrollIntoView() method, but we need to grab the component's underlaying HTML element to access it.
First, let's convert our example to a React functional component.
jsx
We could still give the <h1> element an id attribute. But to do it the React way, we'll give a reference instead with the useRef hook. You can read more about the useRef() hook in the official React documentation.
jsx
Now we need to handle the user clicking the button to scroll back to the top. We can use an onClick event handler for that. You can read more about event handling in the official React documentation.
jsx
Within the event handler, we now have access to the title element through its reference. And we can scroll to the title element like we did in the vanilla JavaScript example.
jsx
By using useRef() in a React component, we have an entry to the underlaying HTML element. This gives us full access to all of the powerful DOM APIs.
Scroll to a React component
Now that we have seen how we can scroll to an element by using a reference. We can utilize that same method to scroll to a React component. By forwarding the reference to the root element of the component, we again have access to the HTML element from outside the component.
jsx
As you may see in the example, we've used the forwardRef() method, to allow other components to access HTML elements within our Article component by reference. You can read more about the forwardRef() method in the official React documentation.
Bonus: scroll to the first error in a Formik form
To apply what we've learned to a real-world use case. Let's imagine we have a large React form using the Formik library to handle submission and validation. For example the following newsletter signup form.
jsx
When a user tries to submit the form, it will display an error saying that the email field is required. In this small form the user will notice this immediately. But when the form grows larger, it would be nice to scroll the error into the viewport so the user notices the error.
We can do this by creating a small helper component that we add to the form.
jsx
Now add this <ErrorFocus> component to our Formik form and the user is automatically scrolled to the first input that has a validation error.
jsx
Closing thoughts
By using useRef() and forwardRef() in your React applications, you will have a lot of powerful DOM APIs at your disposal. In this article we've only focussed on Element.scrollIntoView(), but there are many more cool and handy methods you can use.
Did you know that you can even animate elements through JavaScript? The MDN web documentation will tell you more about this Element.animate() method.