DEV Community

Spencer Carli
Spencer Carli

Posted on • Originally published at reactnativeschool.com

Handling Deep Links with React Navigation

This lesson was originally publish on React Native School. If you're interested in accessing 110+ React Native articles then be sure to visit!

Once you've configured deep linking in your app, which you can learn how to do here (Expo, React Native CLI), what happens once the app opens?

In this lesson we'll configure an app to automatically navigate to the right screen based on the deep linking url.

The app we're starting with grabs a list of people from the Star Wars API and displays their details on a details screen.

You can clone this starter project on Github.

We want to set up our app so that it will automatically open up to a detail screen and get the relevant data.

To accomplish that we'll need to do a few things

  1. Enable deep linking in the app (Done)
  2. Configure deep linking in React Navigation
  3. Request person information from data passed in our deep link

Configuring Deep Linking in React Navigation

First, we need to define a path for each of the navigators in the tree. By that I mean that, since we want to set up deep linking to the Details screen we'll also need to set up a path for its parent navigator listing MainApp.

App/index.js

// ...

const MainApp = createStackNavigator({
  List: {
    screen: List,
    navigationOptions: {
      headerTitle: 'People',
    },
    path: 'list',
  },
  Details: {
    screen: Details,
    navigationOptions: {
      headerTitle: 'Details',
    },
    path: 'details',
  },
});

const App = createSwitchNavigator({
  Initializing,
  MainApp: {
    screen: MainApp,
    path: '',
  },
});

// ...
Enter fullscreen mode Exit fullscreen mode

We're also going to need to be able to pass variables to /details. We can designate that by adding a parameter prefixed by :.

// ...

const MainApp = createStackNavigator({
  List: {
    screen: List,
    navigationOptions: {
      headerTitle: 'People',
    },
    path: 'list',
  },
  Details: {
    screen: Details,
    navigationOptions: {
      headerTitle: 'Details',
    },
    path: 'details/:personId',
  },
});
Enter fullscreen mode Exit fullscreen mode

This will allow us to pass a dynamic value such as /details/3.

Next, we need to tell React Navigation what our uriPrefix. This is whatever you configured within Xcode or AndroidManifest.xml.

If you're using Expo then the prefix is going to be different between development and a published app. Fortunately. Expo makes it easy to build the right uriPrefix.

import { Linking } from 'expo';

// ...

const AppContainer = createAppContainer(App);

export default () => {
  const prefix = Linking.makeUrl('/');
  console.log(prefix);

  // if not using expo then prefix would simply be `swapi://`

  return <AppContainer uriPrefix={prefix} />;
};

// ...
Enter fullscreen mode Exit fullscreen mode

I'm logging prefix so we know what to use when opening the url.

The app should now be configured to accept and handle deep linking. To test it run the following command:

Terminal

# iOS
xcrun simctl openurl booted exp://127.0.0.1:19000/--/details/3

# Android
adb shell am start -W -a android.intent.action.VIEW -d "exp://127.0.0.1:19004/--/details/3" com.deeplinking
Enter fullscreen mode Exit fullscreen mode

If you're not using expo, or it's a live app, it would look like:

Terminal

# iOS
xcrun simctl openurl booted swapi://details/3

# Android
adb shell am start -W -a android.intent.action.VIEW -d "swapi://details/3" com.deeplinking
Enter fullscreen mode Exit fullscreen mode

Deep Link Demo

Request Person Information from Data Passed in Deep Link

Obviously we don't have any data yet. To fix this we need to grab the person id and make a request. To access the personId we just need to use this.props.navigation.getParam('personId') like we would grab any other param.

First we'll check if a full item is passed. If a full item is not passed then we'll try to grab the personId and make a request.

App/screens/Details

// ...

class DetailsScreen extends React.Component {
  // ...

  componentDidMount() {
    const item = this.props.navigation.getParam('item', {});

    if (Object.keys(item).length === 0) {
      const personId = this.props.navigation.getParam('personId', 1);
      fetch(`https://swapi.co/api/people/${personId}`)
        .then(res => res.json())
        .then(res => {
          const data = [];

          Object.keys(res).forEach(key => {
            data.push({ key, value: `${res[key]}` });
          });

          this.setState({ data });
        });
    } else {
      const data = [];

      Object.keys(item).forEach(key => {
        data.push({ key, value: `${item[key]}` });
      });

      this.setState({ data });
    }
  }

  // ...
}

// ...
Enter fullscreen mode Exit fullscreen mode

Final Demo

And there you have it! That's how you configure and interact with deep links in your React Native app.

You can find the final code on Github.

Have a React Native question? Let me know!

Top comments (0)