我正在尝试学习如何使用react-native,所以我建立了一个小应用程序,从服务器获取用户列表,将其显示在列表视图中,按下一行打开一个显示用户数据的屏幕.
我设置了一个导航器,从一个屏幕到另一个屏幕.按下行时我可以打开一个新屏幕,但我无法想象如何将数据传递到这个新屏幕.
我在index.android.js中设置了一个导航器
import React from 'react'; import { AppRegistry,Navigator,} from 'react-native'; import ContactList from './src/containers/ContactList.js'; function MyIndex() { return ( <Navigator initialRoute={{ name: 'index',component: ContactList }} renderScene={(route,navigator) => { if (route.component) { return React.createElement(route.component,{ navigator }); } return undefined; }} /> ); } AppRegistry.registerComponent('reactest',() => MyIndex);
首先,我显示一个带有按钮和空列表视图的屏幕(ContactList.js),按下按钮后,我获取了一些用于更新列表视图的JSON数据:
import React,{ Component,PropTypes } from 'react'; import { Text,View,TouchableOpacity,TouchableHighlight,ListView,Image,} from 'react-native'; import styles from '../../styles'; import ContactDetails from './ContactDetails'; const url = 'http://api.randomuser.me/?results=15&seed=azer'; export default class ContactList extends Component { static propTypes = { navigator: PropTypes.object.isrequired,} constructor(props) { super(props); const datasource = new ListView.DataSource({ rowHasChanged: (r1,r2) => r1 !== r2 }); this.state = { jsonData: datasource.cloneWithRows([]),ds: datasource,}; } _handlePress() { return fetch(url) // convert to json .then((response) => response.json()) // do some string manipulation on json .then(({ results }) => { const newResults = results.map((user) => { const newUser = { ...user,name: { title: `${user.name.title.charAt(0).toUpperCase()}${user.name.title.slice(1)}`,first: `${user.name.first.charAt(0).toUpperCase()}${user.name.first.slice(1)}`,last: `${user.name.last.charAt(0).toUpperCase()}${user.name.last.slice(1)}`,},}; return newUser; }); return newResults; }) // set state .then((results) => { this.setState({ jsonData: this.state.ds.cloneWithRows(results),}); }); } renderRow(rowData: string) { return ( <TouchableHighlight onPress={() => { this.props.navigator.push({ component: ContactDetails,}); }} > <View style={styles.listview_row}> <Image source={{ uri: rowData.picture.thumbnail }} style={{ height: 48,width: 48 }} /> <Text> {rowData.name.title} {rowData.name.first} {rowData.name.last} </Text> </View> </TouchableHighlight> ); } render() { const view = ( <View style={styles.container}> <TouchableOpacity onPress={() => this._handlePress()} style={styles.button} > <Text>Fetch results?</Text> </TouchableOpacity> <ListView enableEmptySections dataSource={this.state.jsonData} renderRow={(rowData) => this.renderRow(rowData)} onPress={() => this._handleRowClick()} /> </View> ); return view; } }
当按下一行时,它会打开一个新的屏幕ContactDetails.js,它应该显示用户的数据:
import React,{ } from 'react'; import { Text,} from 'react-native'; import styles from '../../styles'; export default function ContactDetails() { return ( <View style={styles.container}> <Text>{this.props.title}</Text> <Text>{this.props.first}</Text> <Text>{this.props.last}</Text> </View> ); }
此时我收到了这个错误:
undefined is not an object (evaluating ‘this.props.title’)
我尝试了很多东西,比如:
this.props.navigator.push({ component: ContactDetails,title: rowData.name.title,first: rowData.name.first,last: rowData.name.last,});
要么
this.props.navigator.push({ component: ContactDetails,props: { title: rowData.name.title,} });
要么
this.props.navigator.push({ component: ContactDetails,passProps: { title: rowData.name.title,} });
但无济于事.
我还读到我应该使用redux.难道我做错了什么 ?
编辑:问题在这里:
<TouchableHighlight onPress={() => { this.props.navigator.push({ component: ContactDetails,}); }} >
我想我应该在那里传递一些参数,但无论我在上面尝试过什么都失败了.
所以问题似乎在于:
<Navigator initialRoute={{ name: 'index',component: ContactList }} renderScene={(route,navigator) => { if (route.component) { return React.createElement(route.component,{ navigator }); } return undefined; }} />
在renderScene函数中,您确实收到了路由(并使用route.component),但是您没有传递route.props或route.passProps或者您想要调用它的内容!从我在Navigator的源代码中看到的那一刻起,你应该在创建它时拥有完整的路径对象.所以你应该能够传递你的道具.
例如:
<Navigator initialRoute={{ name: 'index',{ navigator,...route.props }); } return undefined; }} /> // push <TouchableHighlight onPress={() => { this.props.navigator.push({ component: ContactDetails,props: { /* ... */ } }); }} >
您也可以设置redux,但这不是必需的.虽然如果您的应用程序变大,您应该考虑使用外部商店!
更新:
还有另一个问题.
所以它应该是这样的:
export default function ContactDetails(props) { return ( <View style={styles.container}> <Text>{props.title}</Text> <Text>{props.first}</Text> <Text>{props.last}</Text> </View> ); }