Coder Social home page Coder Social logo

Comments (11)

satya164 avatar satya164 commented on May 2, 2024 6

Closing since React Navigation 5 implements prop-based configuration.

from rfcs.

quincycs avatar quincycs commented on May 2, 2024 2

My 2 cents, this is how I accomplished my desire for a dynamic initial route:
quincycs/react-native-q-starter@69f8b76

from rfcs.

lxcid avatar lxcid commented on May 2, 2024 1

My use case is simple, I have a tab navigator that I wan to launch to the specific screen define in the tab.

This is something possible in UITabBarController in iOS.

In my use case, the switch navigator suggestion doesn’t make sense though

from rfcs.

satya164 avatar satya164 commented on May 2, 2024 1

IMO we should be able to pass all navigator and router options as normal props. But for the router it will need a lot of refactoring since they are created at declaration time rather than during render.

from rfcs.

brentvatne avatar brentvatne commented on May 2, 2024

Copying over my comment from #458

if you need to set the initialRouteName as a prop it is because there is some data that you need to fetch asynchronously before you render the app navigation. another way to handle this is to use a switchnavigator and have a screen that you show when you are fetching the async data, then navigate to the appropriate initial route with params when necessary. see https://reactnavigation.org/docs/auth-flow.html for a full example of this.

from rfcs.

slorber avatar slorber commented on May 2, 2024

I want to add my usecase for this RFC, as providing only initialRouteName may not be flexible enough for me.

In my app, I have a "global navigation" that is always mounted, and when the user trigger a process, there's some kind of "command wizzard" that is made using a StackNav of multiple screens, one after the other. This StackNav is not always mounted, it gets mounted only when user starts the command process. And the app need the ability to "restore" the command process, which actually means that we should mount the StackNav with a given initial state and multiple stack screens initially, potentially in different orders, and not just having the ability to set the initial root screen.

A workaround to setup an initial StackNav state on mount is the following:

class CommandScreenNavigator extends React.PureComponent {

  componentDidMount() {
    this.setupInitialNavState();
  }

  setupInitialNavState = () => {
    let initialAction = undefined;

    // Read from parent main app navigation
    const restoreCommandProcessState = this.props.navigation.state.params.restoreCommandProcessState;

    if ( restoreCommandProcessState && restoreCommandProcessState.toScreen === 3 ) {
      initialAction = NavigationActions.reset({
        index: 2,
        actions: [
          NavigationActions.navigate({routeName: FirstScreen}),
          NavigationActions.navigate({routeName: SecondScreen}),
          NavigationActions.navigate({routeName: ThirdScreen}),
        ],
      });
    }
    else if ( restoreCommandProcessState && restoreCommandProcessState.toScreen === 2 ) {
      initialAction = NavigationActions.reset({
        index: 1,
        actions: [
          NavigationActions.navigate({routeName: FirstScreen}),
          NavigationActions.navigate({routeName: SecondScreen}),
        ],
      });
    }
    initialAction && this.stackNavigation.dispatch(initialAction);
  };

  render() {
   const commandWorkflowScreenProps = {...}; 
    return (
      <CommandScreenStackNavigation
        ref={c => this.stackNavigation = c}
        screenProps={commandWorkflowScreenProps}
      />
    );
  }
}

So, instead of ability to set initialRouteName, I think it would be more powerful to give ability to initialise the state of a stateful StackNav, which would actually permit to set an initialRouteName.

Potential workarounds for setting initialRouteName / initialState for my usecase would be:

  • Connecting the StackNav to my main app nav (making it stateless), and then when navigating to the command workflow screen, mount child stacknav with sub-actions
  • Make the stacknav stateless and store the state one step above (in React component or in Redux), using addNavigationHelpers etc

from rfcs.

dani-mp avatar dani-mp commented on May 2, 2024

I think the tab navigator example is a good one: when presenting it, you may want to show a different default tab based on the screen props, for instance. Similar with a switch navigator. You could navigate from the outside to the proper screen, but I rather present the navigation with some props and let it decide its initial state.

In a stack navigator, maybe I have a three steps stack (A, B, C) where A contains a list and B is a details screen. I may want to show the navigator either starting from A, where I can fetch some items and show their details, or if I have already an item, I can skip A and show B directly.

from rfcs.

harvey-woo avatar harvey-woo commented on May 2, 2024

As @satya164 said, I pass router options as props to navigator, I think this has already met the demand. but I still need some official documentation or feature for this situation.

from rfcs.

dani-mp avatar dani-mp commented on May 2, 2024

Hi, @harvey-woo. Can you share a small example with us?

from rfcs.

harvey-woo avatar harvey-woo commented on May 2, 2024

@danielmartinprieto
I just simply create a routerConfig2Navigator function to convert routerConfig to Navigator component

const type2NavigatorComponentCreater = {
  switch: createSwitchNavigator,
  bottomTab: createBottomTabNavigator
}

type Component = FunctionComponent | React.ComponentClass

type RouterConfig = {
  type: keyof typeof type2NavigatorComponentCreater,
  initialRouteName ?: string,
  transitionConfig: () => any,
  routes: {
    [key: string] : RouterConfig | Component
  }
} & {
  [ otherConfig: string ]: any
}
function isComponent(target: any): target is Component {
  return typeof target === 'function'
}

function routerConfig2Navigator(routerConfigOrComponent: RouterConfig | Component, initialRouteNames ?: string[]) {
  if (isComponent(routerConfigOrComponent)) {
    return routerConfigOrComponent
  }
  const { routes, type, ...options } = routerConfigOrComponent
  let initialRouteName: string | undefined
  let subInitialRouteNames: string[]
  if (initialRouteNames && initialRouteNames.length) {
    [ initialRouteName, ...subInitialRouteNames ] = initialRouteNames
  }
  const innerRoutes: { [key: string]: any } = {}
  Object.keys(routes).forEach(key => {
    innerRoutes[key] = routerConfig2Navigator(routes[key], subInitialRouteNames)
  })
  return type2NavigatorComponentCreater[type](innerRoutes, {
    ...options,
    ...(initialRouteName ? {
      initialRouteName
    }: {})
  })
}
const routerConfig: RouterConfig = {
  type: 'switch',
  initialRouteName: 'Login',
  routes: {
    Login,
    Home: {
      type: 'bottomTab',
      tabBarComponent: HomeFooterTab,
      initialRouteName: 'HomeMy',
      routes: {
        HomeIndex,
        HomeRecord,
        HomeMy
      }
    }
  }
}

export default class App extends Component {
  render() {
    const RouterContainer = createAppContainer(routerConfig2Navigator(routerConfig, ['Login']))
    const content = <RouterContainer></RouterContainer>
    return <RouterContainer></RouterContainer>
  }
}

from rfcs.

rajeevrocker7 avatar rajeevrocker7 commented on May 2, 2024

const TabsNav = createBottomTabNavigator({
A: stackA,
B: stackB,
C: stack C
}, {
order: ['A', 'B', 'C'],
initialRouteName: 'A', //<-- want to change this acc. to “this.props.navigation.getParam('fromWhere', ‘’);”
tabBarPosition: 'bottom',
});

//say I have a component 'HomeDash'

//SCREEN
render() {
return (
<HomeDashContainer
ref={nav => (this.homeDashRef = nav)}
screenProps={{ homeDashNav: this.props.navigation }} />
);
}

const HomeDashContainer = createAppContainer(TabsNav);

export default HomeDash;


// I have required route name in an async method that I called in constructor or UNSAFE_componentWillMount

My requirement is to set initial tab on basis of “this.props.navigation.getParam('fromWhere', ‘’);”

Any running solution will be helpful…

from rfcs.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.