React Navigator StackNavigator:从同一场景调用两次时 goBack 不起作用

Posted

技术标签:

【中文标题】React Navigator StackNavigator:从同一场景调用两次时 goBack 不起作用【英文标题】:React Navigator StackNavigator: goBack does not work when called twice from the same scene 【发布时间】:2017-11-14 13:47:03 【问题描述】:

假设我想实现一个具有目录结构的文件浏览器。我创建了一个 React Native 组件,它列出了特定文件夹的文件和目录。当我单击一个文件夹时,我希望进入新文件夹并列出其文件和文件夹。显然,我希望能够使用相同的 React 组件来渲染不同的文件夹。

我使用StackNavigator。这是我的代码

这是我的尝试,但不起作用:

import React,  Component  from 'react';
import 
  AppRegistry,
  BackHandler,
  ListView,
  StyleSheet,
  Text,
  TouchableNativeFeedback,
  View
 from 'react-native';

import 
  StackNavigator,
 from 'react-navigation';

export default class FileExplorerScene extends Component 
  // Initialize the hardcoded data
  constructor(props) 
    super(props);

    // Empty list before adding entries
    const ds = new ListView.DataSource(rowHasChanged: (r1, r2) => r1 !== r2 );
    this.state = 
      dataSource: ds.cloneWithRows(['a', 'b', 'c'])
    ;
  

  onPress(rowData) 
    console.log("onPress(" + rowData + ")");
    this.props.navigation.navigate('FileExplorer',  parent: rowData );
  

  goBack() 
    this.props.navigation.goBack();
    return true;
  

  componentWillMount() 
    BackHandler.addEventListener('hardwareBackPress', this.goBack.bind(this));
  

  renderRow(rowData, sectionID, rowID) 
    return (
      <TouchableNativeFeedback onPress= () =>  this.onPress(rowData); >
        <Text style= margin:5, fontSize: 20> rowData </Text>
      </TouchableNativeFeedback>
      );
  

  render() 
    const  params  = this.props.navigation.state;

    var currentPath;
    if (params) 
      currentPath = (<Text style= margin:10, fontSize: 24>Current Path: params.parent</Text>);
     else 
      currentPath = (<Text style= margin:10, fontSize: 24>Root path</Text>);
    

    return (
      <View>
         currentPath 
        <ListView
          dataSource=this.state.dataSource
          renderRow=this.renderRow.bind(this)
          enableEmptySections=true
        />
      </View>
    );
  


const App = StackNavigator(
  
    FileExplorer:  screen: FileExplorerScene ,
  ,
    headerMode: 'none',
  
);

AppRegistry.registerComponent('ReactProject', () => App);

点击一个:我可以看到Current Path: a

I/ReactNativeJS( 1125): onPress(a)
I/ReactNativeJS( 1125): 'Navigation Dispatch: ',  action: 
I/ReactNativeJS( 1125):     type: 'Navigation/NAVIGATE',
I/ReactNativeJS( 1125):      routeName: 'FileExplorer',
I/ReactNativeJS( 1125):      params:  parent: 'a' ,
I/ReactNativeJS( 1125):      action: undefined ,
I/ReactNativeJS( 1125):   newState: 
I/ReactNativeJS( 1125):     index: 1,
I/ReactNativeJS( 1125):      routes: 
I/ReactNativeJS( 1125):       [  routeName: 'FileExplorer', key: 'Init-id-1497310673011-0' ,
I/ReactNativeJS( 1125):          params:  parent: 'a' ,
I/ReactNativeJS( 1125):           key: 'id-1497310673011-1',
I/ReactNativeJS( 1125):           routeName: 'FileExplorer'  ] ,
I/ReactNativeJS( 1125):   lastState: 
I/ReactNativeJS( 1125):     index: 0,
I/ReactNativeJS( 1125):      routes: [  routeName: 'FileExplorer', key: 'Init-id-1497310673011-0'  ]  

点击b:可以看到Current Path: b

I/ReactNativeJS( 1125): onPress(b)
I/ReactNativeJS( 1125): 'Navigation Dispatch: ',  action: 
I/ReactNativeJS( 1125):     type: 'Navigation/NAVIGATE',
I/ReactNativeJS( 1125):      routeName: 'FileExplorer',
I/ReactNativeJS( 1125):      params:  parent: 'b' ,
I/ReactNativeJS( 1125):      action: undefined ,
I/ReactNativeJS( 1125):   newState: 
I/ReactNativeJS( 1125):     index: 2,
I/ReactNativeJS( 1125):      routes: 
I/ReactNativeJS( 1125):       [  routeName: 'FileExplorer', key: 'Init-id-1497310673011-0' ,
I/ReactNativeJS( 1125):          params:  parent: 'a' ,
I/ReactNativeJS( 1125):           key: 'id-1497310673011-1',
I/ReactNativeJS( 1125):           routeName: 'FileExplorer' ,
I/ReactNativeJS( 1125):          params:  parent: 'b' ,
I/ReactNativeJS( 1125):           key: 'id-1497310673011-2',
I/ReactNativeJS( 1125):           routeName: 'FileExplorer'  ] ,
I/ReactNativeJS( 1125):   lastState: 
I/ReactNativeJS( 1125):     index: 1,
I/ReactNativeJS( 1125):      routes: 
I/ReactNativeJS( 1125):       [  routeName: 'FileExplorer', key: 'Init-id-1497310673011-0' ,
I/ReactNativeJS( 1125):          params:  parent: 'a' ,
I/ReactNativeJS( 1125):           key: 'id-1497310673011-1',
I/ReactNativeJS( 1125):           routeName: 'FileExplorer'  ]  

点击c:可以看到Current Path: c

I/ReactNativeJS( 1125): onPress(c)
I/ReactNativeJS( 1125): 'Navigation Dispatch: ',  action: 
I/ReactNativeJS( 1125):     type: 'Navigation/NAVIGATE',
I/ReactNativeJS( 1125):      routeName: 'FileExplorer',
I/ReactNativeJS( 1125):      params:  parent: 'c' ,
I/ReactNativeJS( 1125):      action: undefined ,
I/ReactNativeJS( 1125):   newState: 
I/ReactNativeJS( 1125):     index: 3,
I/ReactNativeJS( 1125):      routes: 
I/ReactNativeJS( 1125):       [  routeName: 'FileExplorer', key: 'Init-id-1497310673011-0' ,
I/ReactNativeJS( 1125):          params:  parent: 'a' ,
I/ReactNativeJS( 1125):           key: 'id-1497310673011-1',
I/ReactNativeJS( 1125):           routeName: 'FileExplorer' ,
I/ReactNativeJS( 1125):          params:  parent: 'b' ,
I/ReactNativeJS( 1125):           key: 'id-1497310673011-2',
I/ReactNativeJS( 1125):           routeName: 'FileExplorer' ,
I/ReactNativeJS( 1125):          params:  parent: 'c' ,
I/ReactNativeJS( 1125):           key: 'id-1497310673011-3',
I/ReactNativeJS( 1125):           routeName: 'FileExplorer'  ] ,
I/ReactNativeJS( 1125):   lastState: 
I/ReactNativeJS( 1125):     index: 2,
I/ReactNativeJS( 1125):      routes: 
I/ReactNativeJS( 1125):       [  routeName: 'FileExplorer', key: 'Init-id-1497310673011-0' ,
I/ReactNativeJS( 1125):          params:  parent: 'a' ,
I/ReactNativeJS( 1125):           key: 'id-1497310673011-1',
I/ReactNativeJS( 1125):           routeName: 'FileExplorer' ,
I/ReactNativeJS( 1125):          params:  parent: 'b' ,
I/ReactNativeJS( 1125):           key: 'id-1497310673011-2',
I/ReactNativeJS( 1125):           routeName: 'FileExplorer'  ]  

返回。我可以看到Current Path: b

I/ReactNativeJS( 1125): goBack()
I/ReactNativeJS( 1125): 'Navigation Dispatch: ',  action:  type: 'Navigation/BACK', key: 'id-1497310673011-3' ,
I/ReactNativeJS( 1125):   newState: 
I/ReactNativeJS( 1125):     index: 2,
I/ReactNativeJS( 1125):      routes: 
I/ReactNativeJS( 1125):       [  routeName: 'FileExplorer', key: 'Init-id-1497310673011-0' ,
I/ReactNativeJS( 1125):          params:  parent: 'a' ,
I/ReactNativeJS( 1125):           key: 'id-1497310673011-1',
I/ReactNativeJS( 1125):           routeName: 'FileExplorer' ,
I/ReactNativeJS( 1125):          params:  parent: 'b' ,
I/ReactNativeJS( 1125):           key: 'id-1497310673011-2',
I/ReactNativeJS( 1125):           routeName: 'FileExplorer'  ] ,
I/ReactNativeJS( 1125):   lastState: 
I/ReactNativeJS( 1125):     index: 3,
I/ReactNativeJS( 1125):      routes: 
I/ReactNativeJS( 1125):       [  routeName: 'FileExplorer', key: 'Init-id-1497310673011-0' ,
I/ReactNativeJS( 1125):          params:  parent: 'a' ,
I/ReactNativeJS( 1125):           key: 'id-1497310673011-1',
I/ReactNativeJS( 1125):           routeName: 'FileExplorer' ,
I/ReactNativeJS( 1125):          params:  parent: 'b' ,
I/ReactNativeJS( 1125):           key: 'id-1497310673011-2',
I/ReactNativeJS( 1125):           routeName: 'FileExplorer' ,
I/ReactNativeJS( 1125):          params:  parent: 'c' ,
I/ReactNativeJS( 1125):           key: 'id-1497310673011-3',
I/ReactNativeJS( 1125):           routeName: 'FileExplorer'  ]  

返回。没有变化

I/ReactNativeJS( 1125): goBack()

返回。没有变化

I/ReactNativeJS( 1125): goBack()

我是否正确使用goBack?还是StackNavigator 的问题?

【问题讨论】:

【参考方案1】:

实际上将this.props.navigation.goBack() 替换为this.props.navigation.goBack(null) 就可以了!React Navigation documentation 相当混乱...

现在,一切都如我所愿:

点击a:可以看到Current Path: a

I/ReactNativeJS( 2045): onPress(a)
I/ReactNativeJS( 2045): 'Navigation Dispatch: ',  action: 
I/ReactNativeJS( 2045):     type: 'Navigation/NAVIGATE',
I/ReactNativeJS( 2045):      routeName: 'FileExplorer',
I/ReactNativeJS( 2045):      params:  parent: 'a' ,
I/ReactNativeJS( 2045):      action: undefined ,
I/ReactNativeJS( 2045):   newState: 
I/ReactNativeJS( 2045):     index: 1,
I/ReactNativeJS( 2045):      routes: 
I/ReactNativeJS( 2045):       [  routeName: 'FileExplorer', key: 'Init-id-1497998297948-0' ,
I/ReactNativeJS( 2045):          params:  parent: 'a' ,
I/ReactNativeJS( 2045):           key: 'id-1497998297948-1',
I/ReactNativeJS( 2045):           routeName: 'FileExplorer'  ] ,
I/ReactNativeJS( 2045):   lastState: 
I/ReactNativeJS( 2045):     index: 0,
I/ReactNativeJS( 2045):      routes: [  routeName: 'FileExplorer', key: 'Init-id-1497998297948-0'  ]  

点击b:可以看到Current Path: b

I/ReactNativeJS( 2045): onPress(b)
I/ReactNativeJS( 2045): 'Navigation Dispatch: ',  action: 
I/ReactNativeJS( 2045):     type: 'Navigation/NAVIGATE',
I/ReactNativeJS( 2045):      routeName: 'FileExplorer',
I/ReactNativeJS( 2045):      params:  parent: 'b' ,
I/ReactNativeJS( 2045):      action: undefined ,
I/ReactNativeJS( 2045):   newState: 
I/ReactNativeJS( 2045):     index: 2,
I/ReactNativeJS( 2045):      routes: 
I/ReactNativeJS( 2045):       [  routeName: 'FileExplorer', key: 'Init-id-1497998297948-0' ,
I/ReactNativeJS( 2045):          params:  parent: 'a' ,
I/ReactNativeJS( 2045):           key: 'id-1497998297948-1',
I/ReactNativeJS( 2045):           routeName: 'FileExplorer' ,
I/ReactNativeJS( 2045):          params:  parent: 'b' ,
I/ReactNativeJS( 2045):           key: 'id-1497998297948-2',
I/ReactNativeJS( 2045):           routeName: 'FileExplorer'  ] ,
I/ReactNativeJS( 2045):   lastState: 
I/ReactNativeJS( 2045):     index: 1,
I/ReactNativeJS( 2045):      routes: 
I/ReactNativeJS( 2045):       [  routeName: 'FileExplorer', key: 'Init-id-1497998297948-0' ,
I/ReactNativeJS( 2045):          params:  parent: 'a' ,
I/ReactNativeJS( 2045):           key: 'id-1497998297948-1',
I/ReactNativeJS( 2045):           routeName: 'FileExplorer'  ]  

点击c:可以看到Current Path: c

I/ReactNativeJS( 2045): onPress(c)
I/ReactNativeJS( 2045): 'Navigation Dispatch: ',  action: 
I/ReactNativeJS( 2045):     type: 'Navigation/NAVIGATE',
I/ReactNativeJS( 2045):      routeName: 'FileExplorer',
I/ReactNativeJS( 2045):      params:  parent: 'c' ,
I/ReactNativeJS( 2045):      action: undefined ,
I/ReactNativeJS( 2045):   newState: 
I/ReactNativeJS( 2045):     index: 3,
I/ReactNativeJS( 2045):      routes: 
I/ReactNativeJS( 2045):       [  routeName: 'FileExplorer', key: 'Init-id-1497998297948-0' ,
I/ReactNativeJS( 2045):          params:  parent: 'a' ,
I/ReactNativeJS( 2045):           key: 'id-1497998297948-1',
I/ReactNativeJS( 2045):           routeName: 'FileExplorer' ,
I/ReactNativeJS( 2045):          params:  parent: 'b' ,
I/ReactNativeJS( 2045):           key: 'id-1497998297948-2',
I/ReactNativeJS( 2045):           routeName: 'FileExplorer' ,
I/ReactNativeJS( 2045):          params:  parent: 'c' ,
I/ReactNativeJS( 2045):           key: 'id-1497998297948-3',
I/ReactNativeJS( 2045):           routeName: 'FileExplorer'  ] ,
I/ReactNativeJS( 2045):   lastState: 
I/ReactNativeJS( 2045):     index: 2,
I/ReactNativeJS( 2045):      routes: 
I/ReactNativeJS( 2045):       [  routeName: 'FileExplorer', key: 'Init-id-1497998297948-0' ,
I/ReactNativeJS( 2045):          params:  parent: 'a' ,
I/ReactNativeJS( 2045):           key: 'id-1497998297948-1',
I/ReactNativeJS( 2045):           routeName: 'FileExplorer' ,
I/ReactNativeJS( 2045):          params:  parent: 'b' ,
I/ReactNativeJS( 2045):           key: 'id-1497998297948-2',
I/ReactNativeJS( 2045):           routeName: 'FileExplorer'  ]  

返回。我可以看到Current Path: b

I/ReactNativeJS( 2045): goBack()
I/ReactNativeJS( 2045): 'Navigation Dispatch: ',  action:  type: 'Navigation/BACK', key: null ,
I/ReactNativeJS( 2045):   newState: 
I/ReactNativeJS( 2045):     index: 2,
I/ReactNativeJS( 2045):      routes: 
I/ReactNativeJS( 2045):       [  routeName: 'FileExplorer', key: 'Init-id-1497998297948-0' ,
I/ReactNativeJS( 2045):          params:  parent: 'a' ,
I/ReactNativeJS( 2045):           key: 'id-1497998297948-1',
I/ReactNativeJS( 2045):           routeName: 'FileExplorer' ,
I/ReactNativeJS( 2045):          params:  parent: 'b' ,
I/ReactNativeJS( 2045):           key: 'id-1497998297948-2',
I/ReactNativeJS( 2045):           routeName: 'FileExplorer'  ] ,
I/ReactNativeJS( 2045):   lastState: 
I/ReactNativeJS( 2045):     index: 3,
I/ReactNativeJS( 2045):      routes: 
I/ReactNativeJS( 2045):       [  routeName: 'FileExplorer', key: 'Init-id-1497998297948-0' ,
I/ReactNativeJS( 2045):          params:  parent: 'a' ,
I/ReactNativeJS( 2045):           key: 'id-1497998297948-1',
I/ReactNativeJS( 2045):           routeName: 'FileExplorer' ,
I/ReactNativeJS( 2045):          params:  parent: 'b' ,
I/ReactNativeJS( 2045):           key: 'id-1497998297948-2',
I/ReactNativeJS( 2045):           routeName: 'FileExplorer' ,
I/ReactNativeJS( 2045):          params:  parent: 'c' ,
I/ReactNativeJS( 2045):           key: 'id-1497998297948-3',
I/ReactNativeJS( 2045):           routeName: 'FileExplorer'  ]  

返回。我可以看到Current Path: a

I/ReactNativeJS( 2045): goBack()
I/ReactNativeJS( 2045): 'Navigation Dispatch: ',  action:  type: 'Navigation/BACK', key: null ,
I/ReactNativeJS( 2045):   newState: 
I/ReactNativeJS( 2045):     index: 1,
I/ReactNativeJS( 2045):      routes: 
I/ReactNativeJS( 2045):       [  routeName: 'FileExplorer', key: 'Init-id-1497998297948-0' ,
I/ReactNativeJS( 2045):          params:  parent: 'a' ,
I/ReactNativeJS( 2045):           key: 'id-1497998297948-1',
I/ReactNativeJS( 2045):           routeName: 'FileExplorer'  ] ,
I/ReactNativeJS( 2045):   lastState: 
I/ReactNativeJS( 2045):     index: 2,
I/ReactNativeJS( 2045):      routes: 
I/ReactNativeJS( 2045):       [  routeName: 'FileExplorer', key: 'Init-id-1497998297948-0' ,
I/ReactNativeJS( 2045):          params:  parent: 'a' ,
I/ReactNativeJS( 2045):           key: 'id-1497998297948-1',
I/ReactNativeJS( 2045):           routeName: 'FileExplorer' ,
I/ReactNativeJS( 2045):          params:  parent: 'b' ,
I/ReactNativeJS( 2045):           key: 'id-1497998297948-2',
I/ReactNativeJS( 2045):           routeName: 'FileExplorer'  ]  

返回。我可以看到Root path

I/ReactNativeJS( 2045): goBack()
I/ReactNativeJS( 2045): 'Navigation Dispatch: ',  action:  type: 'Navigation/BACK', key: null ,
I/ReactNativeJS( 2045):   newState: 
I/ReactNativeJS( 2045):     index: 0,
I/ReactNativeJS( 2045):      routes: [  routeName: 'FileExplorer', key: 'Init-id-1497998297948-0'  ] ,
I/ReactNativeJS( 2045):   lastState: 
I/ReactNativeJS( 2045):     index: 1,
I/ReactNativeJS( 2045):      routes: 
I/ReactNativeJS( 2045):       [  routeName: 'FileExplorer', key: 'Init-id-1497998297948-0' ,
I/ReactNativeJS( 2045):          params:  parent: 'a' ,
I/ReactNativeJS( 2045):           key: 'id-1497998297948-1',
I/ReactNativeJS( 2045):           routeName: 'FileExplorer'  ]  

返回。不出所料:-)

I/ReactNativeJS( 2045): goBack()

【讨论】:

以上是关于React Navigator StackNavigator:从同一场景调用两次时 goBack 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

底部导航组件组件react-native-tab-navigator的使用

React Native Navigation - 将 Stack Navigator 的 navigationOptions 放入 Bottom Tab Navigator

如何使用 Top Navigator 和 Bottom Navigator 而不让 Top Navigator 与 React Navigation 中的状态栏重叠?

运行 navigator.pop() 后如何刷新 React 状态?

如何在 React Jest 测试中“模拟”navigator.geolocation

React Native学习之自定义Navigator