Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prototype for static navigation config #11144

Merged
merged 16 commits into from Feb 17, 2023
Merged

Conversation

satya164
Copy link
Member

@satya164 satya164 commented Jan 10, 2023

Goal

React Navigation 5+ has a dynamic API which makes it possible to achieve advanced use cases. But it can result in additional boilerplate and duplication. This is a prototype for a static API similar to React Navigation 4 to provide a simpler API for people who don't need dynamic configuration.

This also intends to simplify 2 major issues:

  • Deep link configuration
  • TypeScript configuration

API

Basic usage

const HomeTabs = createBottomTabNavigator({
  screenOptions: {
    tabBarActiveTintColor: "tomato"
  },
  screens: {
    Groups: {
      screen: GroupsScreen,
      linking: "groups"
    },
    Chat: {
      screen: ChatScreen,
      linking: "chat/:id"
    }
  }
});

const RootStack = createStackNavigator({
  screens: {
    Home: HomeTabs,
    Profile: ProfileScreen,
    Feed: {
      screen: FeedScreen,
      options: {
        headerTitle: "My Feed"
      }
    },
    Settings: SettingsScreen
  }
});

const Navigation = createStaticNavigation(RootStack);

export default function App() {
  return (
    <Navigation
      onStateChange={() => {
        // Do something
      }}
    />
  );
}

Documentation

Potential TODOs

  • Add more checks to ensure types are working consistently
  • Add unit tests to ensure functionality
  • Generate linking config based on the path specified
  • Support getComponent for lazy require
  • Add layout/wrapper option for custom UI and logic around the navigator
  • Add ability pass dynamic data to use for options
  • Add if option to conditionally render screens, e.g. for authentication
  • Prevent unknown properties in the config with TypeScript (probably not possible due since no Exact in TS)
  • Add runtime validation for config properties
  • Add JSDoc to all types for static config for better DX
  • Add helper to create a type for the navigation prop preserving navigator specific methods
  • Update warning in NavigationContainer to mention that StaticNavigation already uses it

@codecov-commenter
Copy link

codecov-commenter commented Jan 10, 2023

Codecov Report

Base: 75.38% // Head: 74.33% // Decreases project coverage by -1.06% ⚠️

Coverage data is based on head (20c5624) compared to base (d66e056).
Patch coverage: 9.09% of modified lines in pull request are covered.

📣 This organization is not using Codecov’s GitHub App Integration. We recommend you install it so Codecov can continue to function properly for your repositories. Learn more

Additional details and impacted files
@@            Coverage Diff             @@
##              7.x   #11144      +/-   ##
==========================================
- Coverage   75.38%   74.33%   -1.06%     
==========================================
  Files         181      183       +2     
  Lines        5607     5688      +81     
  Branches     2208     2234      +26     
==========================================
+ Hits         4227     4228       +1     
- Misses       1329     1409      +80     
  Partials       51       51              
Impacted Files Coverage Δ
packages/native/src/createStaticNavigation.tsx 0.00% <0.00%> (ø)
packages/native/src/useLinkProps.tsx 69.04% <ø> (ø)
packages/core/src/StaticNavigation.tsx 2.77% <2.77%> (ø)
packages/core/src/createNavigatorFactory.tsx 83.33% <75.00%> (-16.67%) ⬇️
packages/core/src/getActionFromState.tsx 96.87% <100.00%> (ø)
packages/core/src/useNavigationBuilder.tsx 97.40% <100.00%> (ø)

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

☔ View full report at Codecov.
📢 Do you have feedback about the report comment? Let us know in this issue.

@satya164 satya164 changed the title Proof of concept for static navigation config Prototype for static navigation config Jan 10, 2023
@mdjastrzebski
Copy link
Contributor

@satya164 will users be able to mix static and dynamic navigators in their setup?

I am thinking about scenario when users start with basic static setup, but as the app grows bigger they find that they need to use dynamic nav in one particular navigator.

@satya164
Copy link
Member Author

@mdjastrzebski it'd be possible to use dynamic navigators inside static navigators but not vice-versa.

@ericvicenti
Copy link
Contributor

Looks good to me!

Will we also support this options callback behavior (its a classic 😂)

const RootStack = createStackNavigator({
  screens: {
    Foo: {
      options: ({ navigation }) => ({ ... })

@satya164
Copy link
Member Author

satya164 commented Jan 12, 2023

@ericvicenti yup, it's the same as the dynamic version, so it can be an object or function that receives navigation and route props.

@mdjastrzebski
Copy link
Contributor

@satya164 I am curious:

  1. What would be recommended for new apps/users of React Nav: static or dynamic API?
  2. What criteria should users use to determine which one to use?c

@satya164
Copy link
Member Author

@mdjastrzebski

  1. Dynamic API will stay the default for now. It may change in the future where we document them side-by-side or make the static approach as default.
  2. For now we'd document the problems this API solves and let devs decide for their project. We'd need to spend some time with alpha/beta users to evaluate this and document use cases where static API doesn't work, along with documentation on how to migrate away from the static API.

@satya164 satya164 marked this pull request as ready for review February 17, 2023 16:39
@satya164 satya164 merged commit dc7aaf4 into 7.x Feb 17, 2023
@satya164 satya164 deleted the @satya164/static-navigator branch February 17, 2023 16:39
satya164 added a commit that referenced this pull request Feb 17, 2023
React Navigation 5+ has a dynamic API which makes it possible to achieve advanced use cases. But it can result in additional boilerplate and duplication. This is a prototype for a static API similar to React Navigation 4 to provide a
simpler API for people who don't need dynamic configuration.

This also intends to simplify 2 major issues:

- Deep link configuration
- TypeScript configuration

```js
const HomeTabs = createBottomTabNavigator({
  screenOptions: {
    tabBarActiveTintColor: "tomato"
  },
  screens: {
    Groups: {
      screen: GroupsScreen,
      linking: "groups"
    },
    Chat: {
      screen: ChatScreen,
      linking: "chat/:id"
    }
  }
});

const RootStack = createStackNavigator({
  screens: {
    Home: HomeTabs,
    Profile: ProfileScreen,
    Feed: {
      screen: FeedScreen,
      options: {
        headerTitle: "My Feed"
      }
    },
    Settings: SettingsScreen
  }
});

const Navigation = createStaticNavigation(RootStack);

export default function App() {
  return (
    <Navigation
      onStateChange={() => {
        // Do something
      }}
    />
  );
}
```

- [Getting started](https://github.com/react-navigation/react-navigation.github.io/blob/main/versioned_docs/version-7.x/static-configuration.md)
- [API reference](https://github.com/react-navigation/react-navigation.github.io/blob/main/versioned_docs/version-7.x/static-api-reference.md)
- [TypeScript configuration](https://github.com/react-navigation/react-navigation.github.io/blob/main/versioned_docs/version-7.x/static-typescript.md)
- [Authentication flow](https://github.com/react-navigation/react-navigation.github.io/blob/main/versioned_docs/version-7.x/static-authentication.md)
- [Combining static and dynamic APIs](https://github.com/react-navigation/react-navigation.github.io/blob/main/versioned_docs/version-7.x/static-combine-with-dynamic.md)
satya164 added a commit that referenced this pull request Feb 17, 2023
React Navigation 5+ has a dynamic API which makes it possible to achieve advanced use cases. But it can result in additional boilerplate and duplication. This is a prototype for a static API similar to React Navigation 4 to provide a
simpler API for people who don't need dynamic configuration.

This also intends to simplify 2 major issues:

- Deep link configuration
- TypeScript configuration

```js
const HomeTabs = createBottomTabNavigator({
  screenOptions: {
    tabBarActiveTintColor: "tomato"
  },
  screens: {
    Groups: {
      screen: GroupsScreen,
      linking: "groups"
    },
    Chat: {
      screen: ChatScreen,
      linking: "chat/:id"
    }
  }
});

const RootStack = createStackNavigator({
  screens: {
    Home: HomeTabs,
    Profile: ProfileScreen,
    Feed: {
      screen: FeedScreen,
      options: {
        headerTitle: "My Feed"
      }
    },
    Settings: SettingsScreen
  }
});

const Navigation = createStaticNavigation(RootStack);

export default function App() {
  return (
    <Navigation
      onStateChange={() => {
        // Do something
      }}
    />
  );
}
```

- [Getting started](https://github.com/react-navigation/react-navigation.github.io/blob/main/versioned_docs/version-7.x/static-configuration.md)
- [API reference](https://github.com/react-navigation/react-navigation.github.io/blob/main/versioned_docs/version-7.x/static-api-reference.md)
- [TypeScript configuration](https://github.com/react-navigation/react-navigation.github.io/blob/main/versioned_docs/version-7.x/static-typescript.md)
- [Authentication flow](https://github.com/react-navigation/react-navigation.github.io/blob/main/versioned_docs/version-7.x/static-authentication.md)
- [Combining static and dynamic APIs](https://github.com/react-navigation/react-navigation.github.io/blob/main/versioned_docs/version-7.x/static-combine-with-dynamic.md)
satya164 added a commit that referenced this pull request Feb 17, 2023
React Navigation 5+ has a dynamic API which makes it possible to achieve advanced use cases. But it can result in additional boilerplate and duplication. This is a prototype for a static API similar to React Navigation 4 to provide a
simpler API for people who don't need dynamic configuration.

This also intends to simplify 2 major issues:

- Deep link configuration
- TypeScript configuration

```js
const HomeTabs = createBottomTabNavigator({
  screenOptions: {
    tabBarActiveTintColor: "tomato"
  },
  screens: {
    Groups: {
      screen: GroupsScreen,
      linking: "groups"
    },
    Chat: {
      screen: ChatScreen,
      linking: "chat/:id"
    }
  }
});

const RootStack = createStackNavigator({
  screens: {
    Home: HomeTabs,
    Profile: ProfileScreen,
    Feed: {
      screen: FeedScreen,
      options: {
        headerTitle: "My Feed"
      }
    },
    Settings: SettingsScreen
  }
});

const Navigation = createStaticNavigation(RootStack);

export default function App() {
  return (
    <Navigation
      onStateChange={() => {
        // Do something
      }}
    />
  );
}
```

- [Getting started](https://github.com/react-navigation/react-navigation.github.io/blob/main/versioned_docs/version-7.x/static-configuration.md)
- [API reference](https://github.com/react-navigation/react-navigation.github.io/blob/main/versioned_docs/version-7.x/static-api-reference.md)
- [TypeScript configuration](https://github.com/react-navigation/react-navigation.github.io/blob/main/versioned_docs/version-7.x/static-typescript.md)
- [Authentication flow](https://github.com/react-navigation/react-navigation.github.io/blob/main/versioned_docs/version-7.x/static-authentication.md)
- [Combining static and dynamic APIs](https://github.com/react-navigation/react-navigation.github.io/blob/main/versioned_docs/version-7.x/static-combine-with-dynamic.md)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants