React Native Navigator-路由在第一次导航推送之后才会呈现?

时间:2017-01-03 21:00:33

标签: android ios react-native

我刚刚开始玩React Native,我是一个相对新手。我在使用Navigator组件时遇到问题,我对完成的事情完全不知所措。

我正在尝试设置一个简单的主/细节流程。第一个屏幕只是一个带有几个单元格的ListView,点击一个单元格会推动一个细节屏幕。详细信息屏幕包含静态文本,告诉您刚刚点击的索引以及一个弹出主屏幕的按钮。

然而,我得到了完全奇怪的行为 - 每个单元格的细节屏幕(第一个除外)都无法初始渲染。导航器只是转换为空白屏幕。但是,如果我按下第一个细节屏幕(正确渲染),然后弹出它,然后尝试再次按下,其余的屏幕则按预期正常工作。

这是我的代码:

index.ios.js:

import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  ListView,
  Navigator,
  TouchableOpacity,
} from 'react-native';

//the navigation routes
const routes = [
  {title: 'Main View', index: 0}, //the main screen with the list view
  {title: 'Detail View 1', index: 1},
  {title: 'Detail View 2', index: 2},
  {title: 'Detail View 3', index: 3},
];

import MainList from './MainList'

export default class ReactNativePractice extends Component {

  componentDidMount(){
    console.log("master screen mounted")
  }

  //Navigator render scene function
  renderScene = (route, navigator) => {
    console.log("rendering route index: " + route.index)
      if (route.index === 0){ //the main list. pass in routes and navigator as props.
        return(
          <MainList
            nav={navigator}
            routes={routes}/>
        );
      }
      else{ //the detail screen. pass in route index and navigator as props.
        var indexNum = route.index
        return(
          <DetailView
            num={indexNum}
            nav = {navigator}/>
        );
      }
  }

  render() { //main render function. Set up the navigator
    return(
      <Navigator
        initialRoute={routes[0]}
        initialRouteStack={routes}
        renderScene={this.renderScene}
      />
    );
  }
}

//class for the detail view. Displays static text indicating the just-pressed index
//and a button to go back to the main list.
class DetailView extends Component{
  render(){
    return(
      <View style={styles.container}>
        <Text>{this.props.num}</Text>
        <TouchableOpacity
          onPress={() => {this.props.nav.pop()}}>
          <Text>Go back </Text>
        </TouchableOpacity>
      </View>
    );
  }
}

//#####STYLESHEETS#####
const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  row:{
    padding: 20,
    marginBottom: 1,
    backgroundColor: 'skyblue',
  },
});

AppRegistry.registerComponent('ReactNativePractice', () => ReactNativePractice);

MainList.js:

import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  ListView,
  Navigator,
  TouchableOpacity,
} from 'react-native';

const rows = [
  {id: 0, text: 'row 1'},
  {id: 1, text: 'row 2'},
  {id: 2, text: 'row 3'},
]
const rowHasChanged = (r1, r2) => r1.id !== r2.id
const ds = new ListView.DataSource({rowHasChanged})
export default class MainList extends Component{

  state = {
    dataSource: ds.cloneWithRows(rows)
  }

  //row pressed function- push the corresponding navigation route.
  rowPressed = (rowData) =>{
    this.props.nav.push(this.props.routes[rowData.id+1]) //+1 because routes[0] is the main list view

  }

  renderRow = (rowData) => {
    return(
      <TouchableOpacity
        style={styles.row}
        onPress={() => {this.rowPressed(rowData)}}
      >
        <Text>{rowData.text}</Text>
      </TouchableOpacity>
    )
  }

  render(){
    return(
      <ListView
        style={styles.container}
        dataSource={this.state.dataSource}
        renderRow={this.renderRow}
      />
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  row:{
    padding: 20,
    marginBottom: 1,
    backgroundColor: 'skyblue',
  },
});

我将日志放入控制台,每次调用导航器的renderScene函数时,以及主组件最初安装时都会调用日志。在控制台上检查我的输出,这是我得到的:

在应用启动时:

rendering route index: 0
rendering route index: 1
rendering route index: 2
rendering route index: 3
master screen mounted

单击任何单元格进行第一次导航推送(无论哪一个):

rendering route index: 0

如果我专门点击了第一个单元格,现在我正在尝试将第一个导航弹出回主列表视图:

rendering route index: 0

第一次弹出后再尝试再推(现在一切都适用于每个单元):

rendering route index: 0
rendering route index: [correct index]

显然第一次推送会发生一些事情,因为无论什么路线索引0被渲染而没有别的。但是我不知道我可能做错了什么,或者为什么它似乎在路线索引1上显示第一个屏幕就好了。

非常感谢任何帮助或见解!谢谢!

2 个答案:

答案 0 :(得分:0)

尝试以下。

index.ios.js Navigator组件中的

应为

    <Navigator
      style={{ flex:1 }}
      ref={(nav) => { navigator = nav; }}
      initialRoute={routes[0]}
      renderScene={this.renderScene}
    />
MainList.js

中的

import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  ListView,
  Navigator,
  TouchableOpacity,
} from 'react-native';

const rows = [
  {id: 0, text: 'row 1'},
  {id: 1, text: 'row 2'},
  {id: 2, text: 'row 3'},
]
const rowHasChanged = (r1, r2) => r1.id !== r2.id
const ds = new ListView.DataSource({rowHasChanged})
export default class MainList extends Component{

constructor(props) {
  super(props);
  this.state = {
    dataSource: ds.cloneWithRows(rows)
  };
}



  //row pressed function- push the corresponding navigation route.
  rowPressed = (rowData) =>{
    this.props.nav.push(this.props.routes[rowData.id+1]) //+1 because routes[0] is the main list view

  }

  renderRow = (rowData) => {
    return(
      <TouchableOpacity
        style={styles.row}
        onPress={() => {this.rowPressed(rowData)}}
      >
        <Text>{rowData.text}</Text>
      </TouchableOpacity>
    )
  }

  render(){
    return(
      <ListView
        style={styles.container}
        dataSource={this.state.dataSource}
        renderRow={this.renderRow}
      />
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  row:{
    padding: 20,
    marginBottom: 1,
    backgroundColor: 'skyblue',
  },
});

答案 1 :(得分:0)

感谢Santosh Sharma的回答,我实际上已经找到了问题所在。出于某种原因,将initialRouteinitialRouteStack传递给Navigator导致了此问题。如果我只是传入initialRoute并遗漏initialRouteStack,那么在第一次和随后的推送中它都能完美运行。任何人都有任何洞察原因吗?