How to implement Split View on a tablet with React Native
Tags: reactnative, splitview, tabletview, reactnavigation
Published: 2020-05-29 14:52:08

---
title: How to implement Split View on a tablet with React Native
published: true
description: How to implement Split Views using react-navigation for a tablet!
tags: reactnative, splitview, tabletview, reactnavigation
cover_image: https://canny.io/images/27f13240bdf0cc08ecf57eb29abfcbde.png
---


Tried to implement a Split View I found out the next:

1) [wix/react-native-navigation](https://github.com/wix/react-native-navigation) has support [Split View](https://wix.github.io/react-native-navigation/api/layout-splitView/) on iOS only.
2) [react-navigation](https://reactnavigation.org/) has only feature request for [Tablet dual pane support](https://react-navigation.canny.io/feature-requests/p/tablet-dual-pane-support) 

---

## Is it possible with little effort to get the desired result?

Yes is it!  You can check:

- [split view demo app](https://github.com/retyui/react-native-split-view-demo) 
- open an Expo snack [https://snack.expo.io/split-view](https://snack.expo.io/@retyui/react-native-split-view)

![qr code](https://dev-to-uploads.s3.amazonaws.com/i/yy2cfwjpqyv8n4jw6dkd.png)

---

Someone recommends using an adaptable layout, but if we need to have an ability to "push" screens components into a separate area and support a back gesture (iOS) and a system back (Android)

Let me demonstrate the result before I explain how it works:

| phone               | tablet            |
| ------------------- | ----------------- |
| ![phone](https://dev-to-uploads.s3.amazonaws.com/i/s6r0i3bz65zxzdihfuyi.gif) | ![tablet](https://dev-to-uploads.s3.amazonaws.com/i/wd4g0n3t3yasfaaplirm.gif) |

As you see above when split view enabled some screens opened in left or right areas. It is possible due to two container navigator.

```js
// Main navigator
<NavigationContainer>
  <SplitView>
    <LeftStack />

    // Additional navigator
    {isTablet ? <NavigationContainer
      independent={true}
      /* 
          `independent={true}` Ignore exception when containers are nested within another
          See: https://github.com/react-navigation/react-navigation/commit/d4072e7d885222bc14f33734008f2bd10ff78bc4
      */
    >
      <RightStack />
    </NavigationContainer> : null}
  </SplitView>
</NavigationContainer>
```


And to push a screen to an additional navigator we need to check it is mounted:


```js
const pushChatSettingsScreen = ({userId}) => {
  const args = [CHAT_SETTINGS_SCREEN, {userId}];

  if (isDetailsNavigatorMounted()) {
    return detailsPush(...args);
  }

  return push(...args);
};
```

src: [MessageScreen/navigation.js](https://github.com/retyui/react-native-split-view-demo/blob/2f69ccaef3b45756a664fd9677512f115b1bbaff/src/MessageScreen/navigation.js#L12-L20)

To understand how `push` \ `isDetailsNavigatorMounted` works please check [source code of Navigator](https://github.com/retyui/react-native-split-view-demo/blob/master/src/navigation/Navigator.js)

---

## Support system back on Android

When you try to return to a previous screen using a "system back" on Android you will be faced with the next error:

```sh
The action 'GO_BACK' was not handled by any navigator.

Is there any screen to go back to?
```

It happens because each [NavigationContainer subscribe on hardwareBackPress](https://github.com/react-navigation/react-navigation/blob/9305bfa93901c2a45ecd8b1c17b62883a54b415b/packages/native/src/NavigationContainer.tsx#L41) of [BackHandler](https://reactnative.dev/docs/backhandler). And let see note about listeners invoking:

> The event subscriptions are called in reverse order (i.e. the last registered subscription is called first).

So we have two `<NavigationContainer/>` that subscribed BackHandler and when a user press a back button only the last control all "go hack" behavior

To fix it created a specific HOC [`withSystemBackFix`](https://github.com/retyui/react-native-split-view-demo/blob/master/src/MessageScreen/withSystemBackFix.js) that implement the desired behavior. I wrapped all screens that would be open in split view 

As a result, all screens will be closed in **order** how they were opened:

![android](https://dev-to-uploads.s3.amazonaws.com/i/naken8266gxo4vycgm9j.gif)

---

So use an [example app](https://github.com/retyui/react-native-split-view-demo) to understand all aspects of my implementation of Split View
if you have any question I am glad to discuss them in the comments!

(c) MurAmur