【问题标题】:How to get previous route name from React Navigation如何从 React Navigation 获取以前的路线名称
【发布时间】:2019-09-20 09:27:48
【问题描述】:

我正在尝试将以前的路线名称获取到当前屏幕。因为基于之前的屏幕名称,我必须在当前屏幕中显示/隐藏一些对象。

要获取以前的屏幕名称,我尝试了以下操作

componentDidMount() {
    const { navigation } = this.props;
    if (navigation.state.params && navigation.state.params.previous_screen) {
       console.log('navigation.state.params.previous_screen', navigation.state.params.previous_screen);
    }
}

但是,它在控制台日志中得到了undefined

有什么建议吗?

【问题讨论】:

  • 我检查了,但是,不起作用,并且显示未定义。
  • 以下解决方案无效?
  • 你为什么不接受你的问题的答案?如果提供的答案不起作用,至少评论并说它不起作用。
  • @TenTenPeter 我已经说过我检查过了,但是,没有工作,并且显示未定义。请检查我上面的评论。它没有奏效。即使那些没有奏效,我也不想对他们的答案投反对票。

标签: javascript react-native react-navigation


【解决方案1】:

你需要使用NavigationActions

goToScreen = () => {

  const navigateAction = NavigationActions.navigate({
    routeName: 'Profile',

    params: { previous_screen: 'Home' }, // current screen

    action: NavigationActions.navigate({ routeName: 'Profile' }), // screen you want to navigate to
  });

  this.props.navigation.dispatch(navigateAction);

};

在您的onPress 中调用上述函数

<Text onPress={this.goToScreen}>Go to screen</Text>

在您的其他屏幕中

componentDidMount = () => {

  const { navigation } = this.props;
  if (navigation.state.params && navigation.state.params.previous_screen) {

    this.setState({
      previous_screen: navigation.state.params.previous_screen
    });

  } else {
    console.log("ERROR");
  }
};

Working demo

【讨论】:

    【解决方案2】:
    const navigateAction = NavigationActions.navigate({
      routeName: 'Profile',
      action: NavigationActions.navigate({ routeName: 'Profile', params: { previous_screen: 'Home' } }),
    });
    this.props.navigation.dispatch(navigateAction);
    

    【讨论】:

    • 你应该评论你在这里粘贴的代码,这段代码将如何回答 OP 问题?
    • 仅代码的答案很少有帮助。请评论您的代码或解释为什么这是问题的解决方案。
    【解决方案3】:

    我找到了从当前屏幕找到上一个路线(屏幕)名称的正确方法

     props.navigation.dangerouslyGetParent().state.routes 
    

    您将从导航堆栈中获取屏幕列表(数组)。比如

    输出在这里

    Array(0) [, …]
    0:Object {routeName: "ROUNTE_NAME", key: "id-158*****6785-1"}
    1:Object {params: Object, routeName: "Screen1", key: "Screen1"}
    2:Object {params: Object, routeName: "Screen2", key: "Screen2"}
    

    谢谢大家 - K00L ;)

    【讨论】:

      【解决方案4】:

      使用react-navigation v5,您可以使用路线和索引递归导航状态以找到当前路线。一旦你找到了当前路由,一个没有任何子路由的对象,你可以从索引中减去 1 来得到上一个路由。

      实现这一点的代码类似于

      const getPreviousRouteFromState = (route: NavigationRoute) => {
        let checkRoute = null
        if (route.state && route.state.index > -1 && route.state.routes) {
          checkRoute = route.state.routes[route.state.index]
          if (checkRoute.state && checkRoute.state.routes) {
            return getPreviousRouteFromState(checkRoute)
          }
          const previousRouteIndex = route.state.index - 1
          if (previousRouteIndex > -1) {
            checkRoute = route.state.routes[previousRouteIndex]
          }
        }
        return checkRoute
      }
      

      此策略有一些限制 - 由于堆栈的限制,它会在返回时返回当前路线。切换堆栈时也会返回当前屏幕。

      【讨论】:

      • 你在哪里使用它?屏幕组件中的路由只有keynameparams 键。没有state
      • 我正在这样使用它const navState = useNavigationState((state) =&gt; state) const prevRoute = getPreviousRouteFromState({ state: navState })
      【解决方案5】:

      我使用了以下方法。这可能不是最好的方法,但确实有效。

      let routes = this.props.navigation.dangerouslyGetState().routes[0].state.history;
      for (let idx = routes.length - 1; idx >= 0; idx--) {
        if (routes[idx].type == 'route') {
          let route = routes[idx].key;
          this.props.navigation.navigate(route.substr(0, route.indexOf('-')));
          break;
        }
      }
      

      【讨论】:

        【解决方案6】:

        如果您的导航堆栈被 redux 商店包装,您可以创建一个操作,该操作将在导航容器的状态更改时调度 prev 屏幕值。

        首先,您需要一个 ref 来跟踪您的路线

         const routeNameRef = useRef();
        

        根据文档https://reactnavigation.org/docs/screen-tracking/,您可以像这样获取当前和上一个屏幕

          <NavigationContainer
              .....
              onReady={() => {
                routeNameRef.current = navigationRef.current.getCurrentRoute().name;
              }}
             onStateChange={async () => {
              const previousRouteName = routeNameRef.current;
        
              store.dispatch({
                  type: 'SET_PREV_SCREEN',
                  payload:previousRouteName
              });
        
              routeNameRef.current = currentRouteName;
             }}
        />
        

        【讨论】:

          【解决方案7】:

          app.js | index.js 中定义一些函数。表示初始画面

          setActiveScreen = (activeScreen) => { 
              const previousScreen = this.state.activeScreen
              this.setState({activeScreen: activeScreen, previousScreen: previousScreen})
            }
            goBackScreen = () => {
              this.setState({activeScreen: this.state.previousScreen});
            }
          

          并将此功能传递给导航屏幕

          <Stack.Screen >   
          {(props) => <ComponentScreen goBackScreen={this.goBackScreen} setActiveScreen={this.setActiveScreen} /> }
          </Stack.Screen>
          

          然后在屏幕中使用navigation.goBack() 之前运行goBackScreen

          <TouchableOpacity onPress={() => {
          this.props.goBackScreen()
          this.props.navigation.goBack();
          }}><Text>Click</Text> </TouchableOpacity>
          

          Note:现在可以在activeScreen中获取之前的屏幕名称。这只是可能性的一个例子。你可以试试你自己的想法


          或者你可以在参数中传递上一个屏幕

          navigation.navigate("home", {params: {previousScreen: '{{pass the currentScreen name}}'
          

          然后下一个屏幕你可以通过console.log(this.props.route.params)得到它

          【讨论】:

            【解决方案8】:

            我能够在 react-navigation v6 中动态获取上一个路由名称(来自任何导航器):

            // `navigation` const is passed to the screen component or from useNavigation()
            const routes = navigation.getState()?.routes;
            const prevRoute = routes[routes.length - 2]; // -2 because -1 is the current route
            

            注意:这对于将参数动态传递回前一个屏幕非常有用。不过要注意嵌套路由,语法略有不同。

            if (prevRoute.name === "<Some Routing Key>") {
                  navigation.navigate("<Some Routing Key>", params);
            }
            

            【讨论】:

            • 嘿,谢谢!
            • 为什么我会收到 prevCode 的“名称未定义”警告消息?
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-04-02
            • 2021-10-24
            • 2015-09-14
            • 2011-04-26
            • 1970-01-01
            • 2015-07-14
            相关资源
            最近更新 更多