我刚刚开始玩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上显示第一个屏幕就好了。
非常感谢任何帮助或见解!谢谢!
答案 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的回答,我实际上已经找到了问题所在。出于某种原因,将initialRoute
和initialRouteStack
传递给Navigator
导致了此问题。如果我只是传入initialRoute
并遗漏initialRouteStack
,那么在第一次和随后的推送中它都能完美运行。任何人都有任何洞察原因吗?