React-native-navigation: setStackRoot() not working from the sidemenu in react-native-navigation V2

Created on 29 May 2018  路  19Comments  路  Source: wix/react-native-navigation

Issue Description

When I try to change the root page from home page it will work perfectly, but it not worked from the side menu.
The below code is used in both page(Side menupage and Home page)

js Navigation.setStackRoot(this.props.componentId, { component: { name: 'navigation.SampleRNNavigationV2.SecondPage', options: { topBar: { title: { text: 'Pushed 1' } } } } });

using setRoot from the side menu the page is reset, but it haven't any animation.


Environment

  • React Native Navigation version: 2.0.2305
  • React Native version: 0.54.4
  • Platform(s) (iOS, Android, or both?): Both
  • Device info (Simulator/Device? OS version? Debug/Release?): Simulator

Most helpful comment

You misusing this.props.componentId. Each screen is assigned a unique identifier - componentId. When commands are invoked on a particular screen - that screen's componentId is passed as argument to the command.

If you want to invoke Navigation commands on a particular component, you can assign it an id your self and use that id from anywhere in the app.

In your case, First add an id to the stack:

const stack = {
  id: 'MY_STACK',
  children: [
    {
      component: {}
    },
    {
      component: {}
    }
  ],
  options: {

  }
}

Then, when you want to invoke a command on that stack, use that id:

Navigation.setStackRoot('MY_STACK', {
    component: {
      name: 'navigation.SampleRNNavigationV2.SecondPage',
      options: {
        topBar: {
          title: {
            text: 'Pushed 1'
          }
        }
      }
    }
  });

All 19 comments

You can't change the stack of a screen from another screen.
You have to use Deep Links.
https://wix.github.io/react-native-navigation/#/deep-links

@oscar-omana Thanks for your suggestion.

Deep links working in v1 react-native-navigation. But in V2 haven't mentioned about the Deep link.
Can you Please share sample code of using Deep Links in V2 react-native-navigation.
Shared link getting 404Error

You misusing this.props.componentId. Each screen is assigned a unique identifier - componentId. When commands are invoked on a particular screen - that screen's componentId is passed as argument to the command.

If you want to invoke Navigation commands on a particular component, you can assign it an id your self and use that id from anywhere in the app.

In your case, First add an id to the stack:

const stack = {
  id: 'MY_STACK',
  children: [
    {
      component: {}
    },
    {
      component: {}
    }
  ],
  options: {

  }
}

Then, when you want to invoke a command on that stack, use that id:

Navigation.setStackRoot('MY_STACK', {
    component: {
      name: 'navigation.SampleRNNavigationV2.SecondPage',
      options: {
        topBar: {
          title: {
            text: 'Pushed 1'
          }
        }
      }
    }
  });

@guyca I am try to reset the root from the side menu. Used your suggetion to reset the stack but getting the error.
simulator screen shot - iphone 6 - 2018-05-30 at 14 34 07

Can you reproduce this in the playground app? On which platform?

While checking the playground app, setStackRoot is not used in the sidemenu component(Drawer).

Please note that, setStackRoot action working in the center component, but not from the sidemenu component(From the Drawer).

@Vinu-MysteriousTechVision
If you believe this is a bug, please PR a failing detox e2e test. Thanks 馃憤

@guyca Thanks your kind attention to the issue that I am facing using the 'setStackRoot' action

https://github.com/Vinu-MysteriousTechVision/TestProjectRNNavigationV2/tree/master/Sample3RNNavigationV2

This is a sample project for testing the reset scenario(reset the page from the side menu using setStackRoot).
Can you please verify the given sample project.

Error reproducing stpe:

  1. Tap on side menu(Menu 1 in Drawer) in second time(Reset action using setStackRoot ) getting error.

@guyca I can reproduce it on iOS platform. (not tested on Android)

As a workaround I'm caching the currently visible screen's componentId like this:

Navigation.events().registerComponentDidAppearListener((componentId, componentName) => {
  // cache the currently visible screen componentId for making transitions from a drawer menu
  if (componentName !== 'MainMenuScreen') {
    AppScreens.currentComponentId = componentId
  }
})

Where AppScreens is a singleton that handles app navigation.
Later I'm using the id with Navigation.setStackRoot(AppScreens.currentComponentId, {...}) for making screen transitions on the main stack.

I have fixed the issue.

For managing navigation controller, we have created a singleton class which has an _id field_ used to store the currently active root component id.

Consider in side-menu have two menu options Home and Settings.
When navigating to the root page(Home or Setting), set the component id in a variable in the singleton navigation controller class. This component is used in side-menu to reset the page using the method setStackRoot()

Please find the updated sample project code: https://github.com/Vinu-MysteriousTechVision/TestProjectRNNavigationV2/tree/master/Sample3RNNavigationV2

@guyca The animation is not working correctlty as expected. When resetting to the new page, the previous page is slightly visible.

Documentation already mentioned that setStackRoot() work as similar as push(). But I would like to animate the page without visible on the previous page. So how can create custom animation?

@Vinu-MysteriousTechVision Great job!
That said, I hope you guys are working on a better solution.
This is not an odd behaviour: it's an usual sidebar navigation.

Same issue
setStackRoot() does not work when using on the Drawer.

@doublex Did you try this logic? https://github.com/wix/react-native-navigation/issues/3271#issuecomment-394679775

The project is in the version "react-native-navigation": "^2.0.2314".
The same logic also worked in the latest version.

@Vinu-MysteriousTechVision
Yes, but it's a bad hack.

You can set componentId to the stack and then use that in setStackRoot. No need to cache currentComponentId.

Any progress here?
This is not what you expect from side menu which is used for navigation in 99% situations?
Writing your own controller is not an option, it's real hax

@tanys123 Thanks for your valuable comment.
It's now working using the latest version "react-native-navigation": "^2.0.2556".

When I have integrated the older version of the react-native-navigation-v2("react-native-navigation": "^2.0.2314"),set componentId to the stack and then use that in setStackRoot this approach not worked and I have got the error

ExceptionsManager.js:73 Unhandled JS Exception: The callback setStackRoot() exists in module RNNBridgeModule, but only one callback may be registered to a function in a native module.

In an older version("react-native-navigation": "^2.0.2314"), I have used this #3271 (comment) for managing the side menu(I haven't known its a good approach or not but I have to solve those issue).

_Thanks for the react-native-navigation team for the good navigation library_

Hi,

Center of sideMenu layout is BottomTabs.
So, How can I navigate to one new component screen which is not under bottom tabs from side Menu page..?? thank you

Navigation.events().registerAppLaunchedListener(() => {
  Navigation.setRoot({
      root: {
          sideMenu: {
            center: {
                bottomTabs: [Stack1,Stack2,Stack3]
                },
            right: {
                component: {
                    name: 'SideMenu'
                    }
                },
            }
        }
    });
});

as soon as I can open sideMenu from different screens approach with setting componentId as a constant while the layout initialization doesn't work for me.

Was this page helpful?
0 / 5 - 0 ratings