Valeur de passage entre le composant dans le navigateur natif React

Comment puis-je transmettre des données de sceneA à sceneB avec Navigator dans React Native?

Je l'utilise pour aller à sceneB:

this.props.navigator.push({
    id: "MainPage",
    name: 'mainPage'
});
21
demandé sur rptwsthi 2015-11-20 18:36:54

6 réponses

Vous devez configurer la propriété passProps sur le navigateur. Il y a quelques exemples récents sur le débordement de pile, en particulier ici et ici.

<Navigator
  initialRoute={{name: 'Main', component: Main, index: 0}}
  renderScene={(route, navigator) =>    {
    return React.createElement(<YourComponent />, { ...this.props, ...route.passProps, navigator, route } );
  }} />

Ou

<Navigator
  initialRoute={{name: 'Main', component: Main, index: 0}}
  renderScene={(route, navigator) => {
      <route.component {...route.passProps} navigator={navigator} route={route} />
     }
   }
 />

Si vous cherchez la configuration la plus basique juste pour comprendre la fonctionnalité, j'ai mis en place un projet ici que vous pouvez référencer, et collé le code ci-dessous.

'use strict';

var React = require('react-native');
var {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  Navigator,
  Image,
  TouchableHighlight, TouchableOpacity
} = React;

class Two extends React.Component {
    render(){
    return(
        <View style={{marginTop:100}}>
          <Text style={{fontSize:20}}>Hello From second component</Text>
          <Text>id: {this.props.id}</Text>
          <Text>name: {this.props.name}</Text>
            <Text>name: {this.props.myVar}</Text>
        </View>
    )
  } 
}

class Main extends React.Component {
  gotoNext(myVar) {
   this.props.navigator.push({
      component: Two,
      passProps: {
        id: 'page_user_infos',
        name: 'page_user_infos',
        myVar: myVar,
      }
    })
  }

  render() {
    return(
      <View style={{flex: 4, flexDirection: 'column', marginTop:100}}>
        <TouchableHighlight style={{ height:40, borderWidth:1, marginBottom:10, backgroundColor: '#ddd'}} name='Pole' onPress={ () => this.gotoNext('This is a property that is being passed') }>
          <Text style={{textAlign:'center'}}>Go to next page</Text>
        </TouchableHighlight>
      </View> 
    )
  }
}

class App extends React.Component {
  render() {

    return (
      <Navigator
                style={{flex:1}}
          initialRoute={{name: 'Main', component: Main, index: 0}}
          renderScene={(route, navigator) =>    {
            if (route.component) {
                          return React.createElement(route.component, { ...this.props, ...route.passProps, navigator, route } );
                      }
                }}
          navigationBar={
            <Navigator.NavigationBar routeMapper={NavigationBarRouteMapper} />
      } />
);
}
}


var NavigationBarRouteMapper = {
  LeftButton(route, navigator, index, navState) {
    if(index > 0) {
      return (
      <TouchableHighlight  style={{marginTop: 10}} onPress={() => {
            if (index > 0) {
              navigator.pop();
            } 
        }}>
       <Text>Back</Text>
     </TouchableHighlight>
 )} else {
 return null}
 },
  RightButton(route, navigator, index, navState) {
    return null;
  },
  Title(route, navigator, index, navState) {
    return null
  }
};


var styles = StyleSheet.create({

});

AppRegistry.registerComponent('App', () => App);
27
répondu Nader Dabit 2017-05-23 12:26:01

Je configurerais votre navigateur comme cet exemple . Essentiellement, placez le navigateur dans votre scène d'index et faites y importer tous les composants nécessaires. Ensuite, définissez une fonction renderScene() pour gérer toutes les routes en fonction d'un nom (ou d'un id, comme vous l'avez fait). Je n'utiliserais pas l'objet component comme la chose elle-même qui est transmise de l'appel à la méthode Push du navigateur car si vous faites cela, vous devrez importer le composant dans cette vue spécifique. J'ai l'habitude de le faire et a couru dans de nombreux problèmes, donc je vous préviens juste si vous rencontrez des problèmes, considérez cette approche.

  renderScene(route, navigator) {

    if(route.name == 'root') {
      return <Root navigator={navigator} />
    }
    if(route.name == 'register') {
      return <Register navigator={navigator} />
    }
    if(route.name == 'login') {
      return <Login navigator={navigator} />
    }
    if(route.name == 'home') {
      return <Home navigator={navigator} {...route.passProps} />
    }
    if(route.name == 'update') {
      return <Update navigator={navigator} {...route.passProps} />
    }

  }
4
répondu nbkhope 2016-07-10 04:04:28

Parfois, le pass prop ne fonctionne pas (du moins pour moi) donc ce que je fais est de le passer dans l'objet route lui-même

nav.push({
        id: 'MainPage',
        name: 'LALA',
        token: tok
      });

Donc, pour y accéder dans la scène suivante, j'utilise

var token = this.props.navigator.navigationContext.currentRoute.token;

Bien qu'un "accès" compliqué mais infaillible, les accessoires pass puissent fonctionner ou non de cette façon, vous pouvez passer les propriétés de l'objet route lui-même, vous évitant ainsi les tracas de l'envoyer d'une manière différente.

Ce n'est peut-être pas la bonne façon, mais je la trouve un peu plus pratique.

0
répondu Ronak Khandelwal 2016-06-03 11:03:20

Si vous utilisez réagir indigènes de la navigation, il suffit d'ajouter passProps votre params objet, selon documentation.

Par exemple.:

this.props.navigator.push({
  screen: 'example.Screen',
  title: 'Screen Title',
  passProps: {
    id: 'MainPage',
    name: 'mainPage'
  }
})
0
répondu danielfeelfine 2016-10-31 04:08:03

Vous pouvez également passer des paramètres à sceneA à sceneB en utilisant la manière suivante. Supposons que _handlePressOnClick() est écrit sur un clic de bouton dans L'écran SceneA.

_handlePressOnClick(){ //this can be anything
 this.props.navigator.push({
    name: "sceneB", //this is the name which you have defined in _renderScene
    otherData: {
      dataA: "data1"
    }
 })
}

Ensuite défini des données dans votre _renderScene où vous avez implémenté votre navigateur comme ceci

_renderScene(route, navigator) {        
    switch(route.name) {
        case "sceneA":
            return (
                <sceneA navigator={navigator} />
            );
        break;
        case "sceneB":
            return (
                <sceneB navigator={navigator} otherData={route.otherData}/>
            );
        break;
  }

N'oubliez pas d'importer vos fichiers de vues comme ceci

import sceneA from './sceneA';
import sceneB from './sceneB';

Maintenant, dans le fichier sceneB, vous pouvez accéder à votre otherData de la manière suivante

var {dataA} = this.props.otherData;

or

constructor(props){
  super(props);
  this.state={
     otherData: this.props.otherData
  }
}

Ensuite, dans votre méthode render (), vous pouvez accéder à otherData à l'aide de l'état.

<Text>{this.state.otherData.dataA}</Text>

Vous pouvez également utiliser pour maintenir l'état de niveau global en utilisant redux qui est accessible via action et props automatiquement.

0
répondu Satish Sojitra 2017-02-06 17:24:47

1.Lors du passage des données de la scène A à la scène B, vous devez spécifier dans la balise navigator que vous transmettez également les données avec route. ex.

if(route.name == 'home') {
      return <Home navigator={navigator} data={route.data} />
    }

Envoyer des données de la scène A ex.this.props.navigator.push({name:'sceneB',data:{name:this.state.name},});

Dans la scène B accéder aux données comme ceci ex. this.props.data.name et vous obtenez les données de la scène A à la scène B

0
répondu Pravin Ghorle 2017-03-28 09:28:12