【问题标题】:React Native Navigator- routes not rendering until after the first navigation push?React Native Navigator-在第一次导航推送之后才呈现路线?
【发布时间】:2017-01-03 21:00:33
【问题描述】:

我刚刚开始使用 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 处显示第一个屏幕很好。

任何帮助或见解将不胜感激!谢谢!

【问题讨论】:

  • 也许可以试试this.renderScene.bind(this)
  • @NaderDabit 作为Navigator 组件的renderScene 属性的参数,我会将它放在哪里?我只是尝试过,它对行为没有任何影响。
  • 啊,我明白了,你说得对,应该没什么区别!我不确定,可能与样式或 initialRouteStack 有关。

标签: android ios react-native


【解决方案1】:

尝试关注。

index.ios.jsNavigator组件中应该是

    <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',
  },
});

【讨论】:

  • 谢谢,这很好用,事实上,正如我自己的回答中提到的那样,我能够查明导致问题的原因。
【解决方案2】:

因此,感谢 Santosh Sharma 的回答,我实际上已经查明了问题所在。出于某种原因,将initialRouteinitialRouteStack 都传递给Navigator 导致了这个问题。如果我只是传入initialRoute 并忽略initialRouteStack,它会在第一次和后续推送中完美运行。有人对此原因有任何见解吗?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多