How to deep link in React Native pt.2 — Scroll to Element

Natko Biscan
4 min readNov 19, 2020

This is the second part of my React Native Deep Linking series. Please follow this link to read the first part.

A nice addition to deep linking, mainly with scrollable pages, is the automatic scrolling animation to a specific element. It is mostly used in lists of homogeneous data, such as comments. It helps users see the exact element of their concern in an array of similar data. Say someone liked or replied to your comment and you received a notification. When you tap on it — you are taken to the comment list and it scrolls directly to the mentioned comment. Perfect.

This technique is often paired with some sort of a signal to mark the comment, like contrasting color highlights behind it or an animation of sorts.

So let’s see your options.

Flat List

The easiest way to get this working is to use the FlatList component — if it is compatible with your data on that screen. The important steps are:

1. Add reference to your FlatList:

<FlatList
ref={ref => {
this.flatListRef = ref;
}}
// … other props …
/>

2. Then you can refer to that list inside your component and execute function:

this.flatListRef.scrollToIndex({
animated: true,
index: itemIndex,
});

3. You also need to define onScrollToIndexFailed, which is Flatlist’s prop:

onScrollToIndexFailed={error => { this.flatListRef.scrollToOffset({
offset: error.averageItemLength * error.index,
animated: true,
});
setTimeout(() => {
if (this.flatListRef !== null) {
this.flatListRef.scrollToIndex({
index: error.index,
animated: true,
});
}
}, 100);
}}

I’ll let RN documentation do the talking for why this is necessary:

Used to handle failures when scrolling to an index that has not been measured yet. Recommended action is to either compute your own offset and scrollTo it, or scroll as far as possible and then try again after more items have been rendered.

And you’re done with the FlatList version — call scrollToIndex and let the magic happen. 🎩🐰

Scroll View

If you don’t have the ability to use FlatList, you can go for a ScrollView and the following configuration. If you are using ScrollView, you probably have mixed data (e.g. an image, title, some buttons under it, etc.).

Unfortunately, in that case, you can’t rely on scrolling to a specific item by using its ID to work “out of the box”, because you’re not exactly rendering a list of similar items here.

One of the solutions is to determine the desired element’s position on the screen and use it as an anchor point for autoscroll.

1. Once again, define ref on your view.

<ScrollView
ref={ref => {
this.scrollViewRef = ref;
}}
// ...
>

2. Now you can use another method named scrollTo, which looks something like this:

this.scrollViewRef.scrollTo({
animated: true,
y: viewY,
});

The next question that might come up is “how do I get the y value for my element?”. Fear not!

You can use onLayout and attach it to your RN component. onLayout is a prop of any React Native built-in component that originates from a View. That method is invoked on mount and layout changes of the component. Bear in mind — the x and y values are relative to the top left corner of the screen.

3. This is an example of stuff we can get information about regarding our view:

<View
onLayout={event => {
const { layout } = event.nativeEvent;
console.log(‘height:’, layout.height);
console.log(‘width:’, layout.width);
console.log(‘x:’, layout.x);
console.log(‘y:’, layout.y);
}}
>

The one we need here is obviously y. Store it somewhere accessible and use it in scrollTo method for viewY.

Et voilà! 🎉

Pairing it with deep linking

As per the title, let’s pair this feature with deep linking.

You’d want to send the item’s ID or some sort of a primary key through the link like:
demo://home/first/:commentId

Then we can call JS’s findIndex() on our array of data:

const { commentId } = this.props.navigation.state.params;const commentIndex = commentsArr.findIndex(c => c.id === commentId);

and use commentIndex in scrollToIndex() method.

You can find more details on my GitHub repo and the first part of the blog series.

Deep-linking/autoscrolling combo in action

Let me leave you with some bonus tips:

If you need to use the sticky section header with separated data, look no further than React Native’s SectionList component. The use case for this is a notification list with the following section: Today, Yesterday, Older, etc., as seen on popular applications such as Instagram and Facebook.

Other than that, definitely check out the documentation for other commonly used functions for scrolling components like scrollToEnd or refreshControl.

Have fun and stay tuned for more! 📻 😊

Originally posted on:

My profiles:

--

--