如何使用StackNavigator将数据从一个屏幕内的列表传递到下一个屏幕

时间:2017-06-19 09:06:03

标签: javascript react-native react-navigation

我已经开始学习反应原生的,很棒的东西。我已经能够使用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
      },

});

2 个答案:

答案 0 :(得分:1)

基本上,如果您想将数据传递到另一个屏幕。您应该将数据作为导航命令中的对象传递,例如

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

在第二个屏幕上,可以在组件中访问数据,如下所示

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

答案 1 :(得分:0)

其他人在寻找解决方案,我这样做了:

  1. 将导航传递给App.js,如:
  2. &#13;
    &#13;
     <ChatGroups navigation={navigate}/>
    &#13;
    &#13;
    &#13;

    1. 然后在_renderRow(...)上的GroupChats.js中收到它,就像这样:
    2. &#13;
      &#13;
      let navigate=this.props.navigation;
      <TouchableOpacity onPress={() => navigate('SecondScreen')}>
      &#13;
      &#13;
      &#13;