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'
});
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);
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} />
}
}
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.
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'
}
})
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.
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