react-navigation / rfcs

RFCs for changes to React Navigation
Other
88 stars 16 forks source link

[RFC] TabView API change #87

Closed okwasniewski closed 1 year ago

okwasniewski commented 1 year ago

Summary

Change the API of react-native-tab-view to better suit react navigation's API. This will allow preventing a lot of re-renders and performance issues when using TabView together with material-top-tabs.

The idea is to make TabView's API leverage the descriptor pattern which is heavily used in react navigation.

type MaterialTopTabDescriptorMap = Record<
  string,
  MaterialTopTabDescriptor
>;

Basic example

TabView will accept the items array which contains route descriptors.

<TabView
    index={index}
    onIndexChange={onIndexChange}
    items={[
      {
        articles: {
          title: 'Article',
          accessibilityLabel: 'Article',
          renderScene: () => <Article />,
          tabStyle: {},
          testID: 'article',
        },
        contacts: {
          title: 'Contacts',
          accessibilityLabel: 'Contacts',
          renderScene: () => <Contacts />,
          tabStyle: {},
          testID: 'article',
        },
        albums: {
          title: 'Albums',
          accessibilityLabel: 'Albums',
          renderScene: () => <Albums />,
          tabStyle: {},
          testID: 'article',
        },
      },
    ]}
  />

Motivation

Currently, MaterialTopTabs are very slow when compared with using tab-view itself. We are changing TabBar props with every route change because we are looking up options by the currently focused route:

const focusedOptions = descriptors[state.routes[state.index].key].options;

This pattern prevents users to apply different options to tab screens (like different styles for each tab).

This API change will also make tab-view fit more into react navigation ecosystem.

There are multiple issues flagging material-top-tabs being slow: #11047

Adoption strategy

This is a breaking change that would be released together with React Navigation v7.