react-navigation/rfcs

Expose logic for initializing state of createAppContainer

romaricpascal opened this issue · 4 comments

At the moment, the logic behind the initialization of the nav state in createAppContainer is completely inaccessible from the outside. If the state has to be inferred from something else than AsyncStorage (or not be persisted as things go) or a deep link, it makes it hacky to set that initial state.

I've had two main use case for that:

  • setting initial screen from a Firebase opened notification, with that screen not being the first in a navigator. The navigation happened, but a glimpse of the first screen remains visible, which is not a great visual experience. With a way to grab which route to open ahead of the rendering of the main navigator, this would be sorted?
  • setting initial screen based on the app state (eg. whether user is logged in or not).

I could see two ways of going through this:

  • letting a wrapper component compute the initial state based on whatever criteria the app needs. react-navigation could provide deep-linking and async-storage helpers for that
<MyAppContainer initialNavState={{/* routename and params */}} />
  • keeping the magic inside the componentDidMount of the class generated by createAppContainer and providing a "last one wins" list of nav => Promise<nav> function that would update the nav.
<MyAppContainer initializeNav={[fromStorage,fromDeepLink,fromNotification,fromLogin]} />

Does that sound a useful addition?

Hey folks, what if we added the following two new features:

  • initialAction prop on the app container to customize the initial action
  • SET_STATE action that allows you to set the whole navigation state of the navigator, implemented in the routers' getStateForAction

So, if you have an initial route you want to show, you could mount the app container with the following:

<MyAppContainer
  initialAction={NavigationActions.navigate({ routeName: 'SomeRoute' })}
/>

Or if you want to launch with a particular navigation state:

<MyAppContainer
  initialAction={NavigationActions.setState({
    index: 1,
    routes: [ {...}, {...} ]
  })}
/>

This sounds great! That would leave plenty of flexibility for the app to configure the initial state however it needs.

Cheers for having considered this RFC :)

React Navigation 5 accepts an initialState prop which should address this.