2017-06-19 68 views
0

我已經開始學習react-native,令人敬畏的東西。我已經能夠使用StackNavigator在屏幕之間導航。如何使用StackNavigator將數據從一個屏幕內的列表傳遞到下一個屏幕

在一個屏幕上,我顯示一個從靜態json文件填充的列表。點擊一行後,下一個屏幕應該彈出並顯示所選項目的詳細信息。 任何幫助將不勝感激。 我創建了一個要點與所有相關的類https://gist.github.com/SteveKamau72/f04b0a3dca03a87d604fe73767941bf2

也將粘貼在這裏:

/** index.android.js**/ 
 
//This code includes the stack navigation to different screens 
 
import React, { Component } from 'react'; 
 
import { 
 
    AppRegistry, 
 
} from 'react-native'; 
 
import { StackNavigator } from 'react-navigation'; 
 
import SecondScreen from './src/SecondScreen'; 
 
import App from './src/App'; 
 
    
 
class SampleApp extends Component { 
 
    static navigationOptions = { 
 
    title: 'Home Screen', 
 
    }; 
 
    
 
    render(){ 
 
    const { navigation } = this.props; 
 
    
 
    return ( 
 
     <App navigation={ navigation }/> 
 
    ); 
 
    } 
 
} 
 
    
 
const SimpleApp = StackNavigator({ 
 
    Home: { screen: Sasa }, 
 
    SecondScreen: { screen: SecondScreen, title: 'ss' }, 
 
}); 
 
    
 
AppRegistry.registerComponent('SampleApp',() => SimpleApp); 
 
    
 
    
 
    
 
    
 
/** App.js**/ 
 
//This code is for file App.js to display group of chats 
 
    
 
import React, { Component } from 'react'; 
 
import { 
 
    StyleSheet, 
 
    Text, 
 
    Button, 
 
    View 
 
} from 'react-native'; 
 
import { StackNavigator } from 'react-navigation'; 
 
import ChatGroups from './components/ChatGroups'; 
 
    
 
const App = (props) => { 
 
    
 
    const { navigate } = props.navigation; 
 
    
 
    return ( 
 
     
 
    //Here's the problem 
 
    // i am trying to get user row click 
 
    <ChatGroups onUserSelected={this._onUserSelected.bind(this)}/> 
 
); 
 
} 
 
//then show this alert. But this isnt expected to be here and app 'crashes'. 
 
//seems app should return nothin but a component. 
 
    _onUserSelected(user) { 
 
    alert("Selected User:\n" + JSON.stringify(user)) 
 
    
 
} 
 
    
 
export default App 
 
    
 
    
 
/** ChatGroup.js**/ 
 
//This code is component for file App.js to display group of chats 
 
    
 
import React, { Component } from 'react'; 
 
import { 
 
    StyleSheet, 
 
    ListView, 
 
    Text, 
 
    View, 
 
    Image, 
 
    TouchableOpacity 
 
} from 'react-native'; 
 
    
 
const data = [ 
 
    { 
 
     name: "Kasarini", 
 
     last_chat: { 
 
      updated_at:"22:13", 
 
      updated_by: "Steve Kamau", 
 
      chat_message: "Lorem Ipsum is pretty awesome if you know it" 
 
     }, 
 
     thumbnail: "https://randomuser.me/api/portraits/thumb/men/83.jpg" 
 
    
 
    }, 
 
    { 
 
     name: "Kabete", 
 
     last_chat: { 
 
      updated_at:"20:34", 
 
      updated_by: "Tim Mwirabua", 
 
      chat_message: "Lorem Ipsum is pretty awesome if you know it" 
 
     }, 
 
     thumbnail: "https://randomuser.me/api/portraits/thumb/men/83.jpg" 
 
    
 
    }, 
 
    { 
 
     name: "Kiambuu", 
 
     last_chat: { 
 
      updated_at:"19:22", 
 
      updated_by: "Maureen Chubi", 
 
      chat_message: "Lorem Ipsum is pretty awesome if you know it" 
 
     }, 
 
     thumbnail: "https://randomuser.me/api/portraits/thumb/men/83.jpg" 
 
    
 
    }, 
 
    { 
 
     name: "UnderPass", 
 
     last_chat: { 
 
      updated_at:"17:46", 
 
      updated_by: "Faith Chela", 
 
      chat_message: "Lorem Ipsum is pretty awesome if you know it" 
 
     }, 
 
     thumbnail: "https://randomuser.me/api/portraits/thumb/men/83.jpg" 
 
    
 
    }, 
 
] 
 
    
 
export default class UserListView extends Component { 
 
    constructor() { 
 
     super(); 
 
     const ds = new ListView.DataSource({rowHasChanged: this._rowHasChanged}); 
 
    
 
     this.state = { 
 
      dataSource: ds.cloneWithRows(data) 
 
     } 
 
    } 
 
    render() { 
 
     return ( 
 
      <ListView 
 
       dataSource={this.state.dataSource} 
 
       renderRow={this._renderRow.bind(this)} 
 
       enableEmptySections={true} /> 
 
     ) 
 
    } 
 
    
 
    _renderRow(row,sectionId, rowId, highlightRow) { 
 
     var self = this; 
 
     return ( 
 
      <TouchableOpacity onPress={function() { 
 
        highlightRow(sectionId, rowId) 
 
        self.props.onUserSelected(row) 
 
       }}> 
 
       <View style={styles.container}> 
 
        <Image 
 
          style={styles.groupChatThumbnail} 
 
          source={{uri: row.thumbnail}}/> 
 
        <View> 
 
         <View style={{flexDirection:'row', justifyContent:'space-between', width:280}}> 
 
           <Text style={styles.groupNameText}>{row.name} </Text> 
 
           <Text style={styles.groupUpdatedAtText}>{row.last_chat.updated_at}</Text> 
 
    
 
         </View> 
 
         <View style={{ flexDirection:'row', alignItems:'center', marginTop: 5}}> 
 
           <Text style={styles.groupUpdatedByText}>{row.last_chat.updated_by} : </Text>  
 
           <View style={{flex: 1}}> 
 
             <Text ellipsizeMode='tail' numberOfLines={1}style={styles.groupChatMessageText}>{row.last_chat.chat_message} </Text> 
 
           </View> 
 
         </View> 
 
        </View> 
 
         
 
       
 
       </View> 
 
      </TouchableOpacity> 
 
     ) 
 
    } 
 
    
 
    _rowHasChanged(r1, r2) { 
 
     return r1 !== r2 
 
    } 
 
    
 
    
 
     highlightRow() { 
 
    alert('Hi!'); 
 
    } 
 
    
 
} 
 
    
 
const styles = StyleSheet.create({ 
 
    container:{ 
 
     alignItems:'center', 
 
     padding:10, 
 
     flexDirection:'row', 
 
     borderBottomWidth:1, 
 
     borderColor:'#f7f7f7', 
 
     backgroundColor: '#fff' 
 
     }, 
 
     groupChatContainer:{ 
 
     display: 'flex', 
 
     flexDirection: 'row', 
 
     
 
     }, 
 
     groupNameText:{ 
 
     marginLeft:15, 
 
     fontWeight:'600', 
 
     marginTop: -8, 
 
     color: '#000' 
 
     }, 
 
     groupUpdatedAtText :{ 
 
     color:'#333', fontSize:10, marginTop: -5 
 
     }, 
 
     groupChatThumbnail:{ 
 
     borderRadius: 30, 
 
     width: 50, 
 
     height: 50 , 
 
     alignItems:'center' 
 
     }, 
 
     groupUpdatedByText:{ 
 
     fontWeight:'400', color:'#333', 
 
     marginLeft:15, marginRight:5 
 
     }, 
 
    
 
});

更新:

/** index.android.js**/ 
 
//This code includes the stack navigation to different screens 
 
import React, { Component } from 'react'; 
 
import { 
 
    AppRegistry, 
 
} from 'react-native'; 
 
import { StackNavigator } from 'react-navigation'; 
 
import SecondScreen from './src/SecondScreen'; 
 
import App from './src/App'; 
 
    
 
class SampleApp extends Component { 
 
    static navigationOptions = { 
 
    title: 'Home Screen', 
 
    }; 
 
    
 
    render(){ 
 
    const { navigation } = this.props; 
 
    
 
    return ( 
 
     <App navigation={ navigation }/> 
 
    ); 
 
    } 
 
} 
 
    
 
const SimpleApp = StackNavigator({ 
 
    Home: { screen: Sasa }, 
 
    SecondScreen: { screen: SecondScreen, title: 'ss' }, 
 
}); 
 
    
 
AppRegistry.registerComponent('SampleApp',() => SimpleApp); 
 
    
 
    
 
    
 
    
 
/** App.js**/ 
 
//This code is for file App.js to display group of chats 
 
import React, { Component } from 'react'; 
 
import { 
 
StyleSheet, 
 
Text, 
 
Button, 
 
View 
 
} from 'react-native'; 
 
import { StackNavigator } from 'react-navigation'; 
 
import ChatGroups from './components/ChatGroups'; 
 

 
const App = (props) => { 
 
const { navigate } = props.navigation; 
 
return (
 
    <ChatGroups navigation={navigate}/> 
 
); 
 
} 
 

 
export default App 
 

 
    
 
    
 
/** ChatGroup.js**/ 
 
//This code is component for file App.js to display group of chats 
 

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

 
import { StackNavigator } from 'react-navigation'; 
 

 
const data = [ 
 
    { 
 
     name: "Kasarini", 
 
     last_chat: { 
 
      updated_at:"22:13", 
 
      updated_by: "Steve Kamau", 
 
      chat_message: "Lorem Ipsum is pretty awesome if you know it" 
 
     }, 
 
     thumbnail: "https://randomuser.me/api/portraits/thumb/men/83.jpg" 
 

 
    }, 
 
    { 
 
     name: "Kabete", 
 
     last_chat: { 
 
      updated_at:"20:34", 
 
      updated_by: "Tim Mwirabua", 
 
      chat_message: "Lorem Ipsum is pretty awesome if you know it" 
 
     }, 
 
     thumbnail: "https://randomuser.me/api/portraits/thumb/men/83.jpg" 
 

 
    }, 
 
    { 
 
     name: "Kiambuu", 
 
     last_chat: { 
 
      updated_at:"19:22", 
 
      updated_by: "Maureen Chubi", 
 
      chat_message: "Lorem Ipsum is pretty awesome if you know it" 
 
     }, 
 
     thumbnail: "https://randomuser.me/api/portraits/thumb/men/83.jpg" 
 

 
    }, 
 
    { 
 
     name: "UnderPass", 
 
     last_chat: { 
 
      updated_at:"17:46", 
 
      updated_by: "Faith Chela", 
 
      chat_message: "Lorem Ipsum is pretty awesome if you know it" 
 
     }, 
 
     thumbnail: "https://randomuser.me/api/portraits/thumb/men/83.jpg" 
 

 
    }, 
 
] 
 

 
export default class UserListView extends Component { 
 
    constructor() { 
 
     super(); 
 
     const ds = new ListView.DataSource({rowHasChanged: this._rowHasChanged}); 
 

 
     this.state = { 
 
      dataSource: ds.cloneWithRows(data) 
 
     } 
 

 
    } 
 
    render() { 
 
     // const { navigate } = this.props.navigation; 
 
     return (
 
      <ListView 
 
       dataSource={this.state.dataSource} 
 
       renderRow={this._renderRow.bind(this)} 
 
       enableEmptySections={true} /> 
 
     ) 
 
    } 
 

 
    _renderRow(row,sectionId, rowId, highlightRow) { 
 
     var self = this; 
 
     const {navigation} = this.props; 
 
       return (
 
      <TouchableOpacity onPress={() => navigate('SecondScreen')}> 
 
       <View style={styles.container}> 
 
        <Image 
 
          style={styles.groupChatThumbnail} 
 
          source={{uri: row.thumbnail}}/> 
 
        <View> 
 
         <View style={{flexDirection:'row', justifyContent:'space-between', width:280}}> 
 
           <Text style={styles.groupNameText}>{row.name} </Text> 
 
           <Text style={styles.groupUpdatedAtText}>{row.last_chat.updated_at}</Text> 
 

 
         </View> 
 
         <View style={{ flexDirection:'row', alignItems:'center', marginTop: 5}}> 
 
           <Text style={styles.groupUpdatedByText}>{row.last_chat.updated_by} : </Text> 
 
           <View style={{flex: 1}}> 
 
             <Text ellipsizeMode='tail' numberOfLines={1}style={styles.groupChatMessageText}>{row.last_chat.chat_message} </Text> 
 
           </View> 
 
         </View> 
 
        </View> 
 
         
 
       
 
       </View> 
 
      </TouchableOpacity> 
 
     ) 
 
    } 
 

 
    _rowHasChanged(r1, r2) { 
 
     return r1 !== r2 
 
    } 
 

 

 
     highlightRow() { 
 
    alert('Hi!'); 
 
    } 
 

 
} 
 

 
const styles = StyleSheet.create({ 
 
    container:{ 
 
     alignItems:'center', 
 
     padding:10, 
 
     flexDirection:'row', 
 
     borderBottomWidth:1, 
 
     borderColor:'#f7f7f7', 
 
     backgroundColor: '#fff' 
 
     }, 
 
     groupChatContainer:{ 
 
     display: 'flex', 
 
     flexDirection: 'row', 
 
     
 
     }, 
 
     groupNameText:{ 
 
     marginLeft:15, 
 
     fontWeight:'600', 
 
     marginTop: -8, 
 
     color: '#000' 
 
     }, 
 
     groupUpdatedAtText :{ 
 
     color:'#333', fontSize:10, marginTop: -5 
 
     }, 
 
     groupChatThumbnail:{ 
 
     borderRadius: 30, 
 
     width: 50, 
 
     height: 50 , 
 
     alignItems:'center' 
 
     }, 
 
     groupUpdatedByText:{ 
 
     fontWeight:'400', color:'#333', 
 
     marginLeft:15, marginRight:5 
 
     }, 
 

 
});

+0

你可以在[expo](https://snack.expo.io/)中重現問題嗎?以這種方式幫助你會更容易。 – QoP

回答

1

基本上,如果你想傳遞數據到另一個屏幕。你應該通過該數據爲對象的導航命令例如

<TouchableOpacity onPress={() => navigate('SecondScreen', {data_Being_passed })}> 
      <Text> Pass Data </Text> 
</TouchableOpacity > 

在第二個屏幕中的數據可以在組件訪問如下

const { data_Being_passed } = this.props.navigation.state.params; 
+0

是的,雖然我理解這個概念和流程,相信我,我已經嘗試過這個,但不能將導航傳遞給onPress函數。我得到「無法找到變量:導航」。 –

+0

將導航作爲道具傳遞到根組件 –

+0

所以我試圖像''ChatGroups navigation = {navigate} />''那樣傳遞它並在_renderRow裏面接收它,就像'const {navigate} = this.props.navigation;然後使用它'onPress = {()=> navigate('SecondScreen',「random」)}''但我得到'undefined不是函數(評估'navigate(SecondScreen)' –

0

任何人找soluton,我做這樣的:

  1. 通過了導航App.js,如:

<ChatGroups navigation={navigate}/>

  • 然後接收其在上GroupChats.js _renderRow(...)像這樣:
  • let navigate=this.props.navigation; 
     
    <TouchableOpacity onPress={() => navigate('SecondScreen')}>

    相關問題