Je suis nouveau à React Native Je crée un exemple d'application où l'utilisateur peut se connecter et s'inscrire pour un nouveau compte.
J'ai deux cours de React,
L'une est la classe principale index.ios.js et une autre classe appelée register.js. Dans la classe d'index, je dis que si la variable register est vraie, restituer l'écran du registre.
Dans la classe register.js, j'essaie de définir le registre de variable sur false à l'aide de this.setState ({register: false}), mais ne provoque pas le rendu du parent (index.ios.js). La méthode super (state) ou quelque chose de similaire me manque-t-elle? Je crois que l'état parent n'obtient pas les valeurs de la variable de registre mise à jour.
Voici mes cours:
Render dans index.ios.js:
render: function() {
if(this.state.register) {
return this.renderRegisterScreen();
}
else if (this.state.loggedIn) {
return this.userLoggedIn();
}
else {
return this.renderLoginScreen();
}
}
Register.js:
var React = require('react-native');
var {
AppRegistry,
StyleSheet,
Text,
View,
Image,
TouchableHighlight,
TextInput,
} = React;
var Register = React.createClass({
render: function() {
return (
<View style={styles.container}>
<View style={styles.rafitoImage}>
<Image source={require('./logo.png')}></Image>
<Text style={styles.slogan}>Eliminate the need to wait!</Text>
</View>
<View style={styles.bottomSection}>
<View style={styles.username}>
<View style={styles.inputBorder}>
<TextInput placeholder="Username..." style={styles.usernameInput} onChangeText={(text) => this.setState({username: text})}/>
</View>
<View style={styles.inputBorder}>
<TextInput password={true} placeholder="Password..." style={styles.usernameInput} onChangeText={(text) => this.setState({password: text})}/>
</View>
<View style={styles.inputBorder}>
<TextInput password={true} placeholder="Verify Password..." style={styles.usernameInput} onChangeText={(text) => this.setState({verifyPassword: text})}/>
</View>
<View style={styles.inputBorder}>
<TextInput placeholder="Phone.." style={styles.usernameInput} onChangeText={(text) => this.setState({phone: text})}/>
</View>
<View style={styles.inputBorder}>
<TextInput placeholder="Email.." style={styles.usernameInput} onChangeText={(text) => this.setState({email: text})}/>
</View>
<TouchableHighlight style={styles.button}
underlayColor='#f1c40f' onPress={this.register}>
<Text style={styles.buttonText}>Register</Text>
</TouchableHighlight>
<TouchableHighlight style={styles.signUp} onPress={this.resetToLogin}
underlayColor='#ffffff'>
<Text style={styles.signUpText}>Already A Member </Text>
</TouchableHighlight>
</View>
</View>
<View style={styles.copyright}>
</View>
</View>
);
},
resetToLogin: function() {
this.setState({
register: false //I want this to re render the home screen with the variable register as false
});
}
});
var styles = StyleSheet.create({
container: {
flex : 1
},
bottomSection: {
flex: 5,
flexDirection: 'row'
},
button: {
height: 36,
backgroundColor: '#32c5d2',
justifyContent: 'center',
marginTop: 20
},
buttonText: {
fontSize: 18,
color: 'white',
alignSelf: 'center'
},
signUpText: {
color: '#3598dc'
},
signUp: {
alignItems: 'flex-end',
marginTop: 10,
},
username: {
flex: 1,
padding: 5
},
rafitoImage: {
flex: 3,
justifyContent: 'center',
alignItems: 'center',
},
copyright: {
alignItems: 'center'
},
usernameInput: {
height: 36,
marginTop: 10,
marginBottom: 10,
fontSize: 18,
padding: 5
},
copyrightText: {
color: '#cccccc',
fontSize: 12
},
inputBorder: {
borderBottomWidth: 1,
borderBottomColor: '#ececec'
},
slogan: {
color: '#3598dc'
}
});
module.exports = Register;
Tentative 1
Selon la réponse, j'ai ajouté ceci à mon index.ios.js
renderRegisterScreen: function() {
return (
<Register login={this.login}/>
)
}
Et j'ai ajouté ceci à mon register.js
<TouchableHighlight style={styles.signUp} onPress={this.props.login}
underlayColor='#ffffff'>
<Text style={styles.signUpText}>Already A Member </Text>
</TouchableHighlight>
Mais pour une raison quelconque, il n’a même plus accès à l’écran d’enregistrement, il exécute la fonction d’identification dès que l’écran d’enregistrement est rendu. Qu'est-ce qui me manque maintenant? S'il vous plaît donnez votre avis.
Merci
Mettre à jour
Cela fonctionne quand je passe enregistré comme une propriété mais pas quand je ne le fais pas. J'aimerais comprendre pourquoi si quelqu'un pouvait poster ça.
Merci
Vous pouvez transmettre la fonction à l'enfant sous forme d'accessoires, puis définir ainsi l'état du parent depuis l'enfant.
Composant parent:
var Parent = React.createClass({
getInitialState() {
return {
registered: false
}
},
register(){
console.log("logging in... ");
this.setState({
registered: true
});
},
render: function() {
return (
<View style={styles.container}>
<Child register={this.register.bind(this)} registered={this.state.registered} />
{this.state.registered && <View style={{padding:10, backgroundColor:'white', marginTop:10}}>
<Text style={{fontSize:20}}>Congratulations, you are now registered!</Text>
</View>}
</View>
);
}
});
Composant enfant:
var Child = React.createClass({
render: function() {
return(
<View style={{backgroundColor: 'red', paddingBottom:20, paddingTop:20 }}>
<TouchableHighlight style={{padding:20, color: 'white', backgroundColor: 'black'}} onPress={() => this.props.register() }>
{this.props.registered ? <Text style={{color: 'white'}}>registered</Text> : <Text style={{color: 'white'}}>register</Text>}
</TouchableHighlight>
</View>
)
}
})
Voici une solution plus puissante. Cela laissera le composant enfant modifier n'importe quelle variable d'état dans le parent.
Composant parent:
render: function() {
return (
...
<Child setParentState={newState=>this.setState(newState)} />
...
);
}
// Prendre note de la setState ()
Composant enfant:
this.props.setParentState({registered: true})
Pourquoi ma tentative a échoué était parce que j'utilisais
onPress={this.props.login}
CA devrait etre
onPress={()=>this.props.login}
à cause de cette erreur, ma fonction onPress s'exécutait dès que le bouton était rendu. Je ne sais pas pourquoi cela se produit mais je sais quelle était mon erreur.
En utilisant StackNavigator
, j'ai trouvé une âme exploitant screenProps
. Ici, vous pouvez transmettre des fonctions et des valeurs à vos itinéraires. L'état global de l'application est géré dans App
. App
passe ensuite dans les fonctions et/ou l'état à NavComponent
screenProps
. Chaque route enfant dans StackNavigator
aura alors accès via this.props.screenProps
Cette solution fonctionne bien pour l'instant. J'aimerais des commentaires ou des suggestions pour améliorer cette méthode
class HomeScreen extends React.Component {
render() {
return (
<View>
<Text>{JSON.stringify(this.props.screenProps.awesome)}</Text>
<Button
onPress={() => this.props.screenProps.updateGlobalState("data")}
title="Update parent State"
/>
</View>
);
}
}
const NavComponent = StackNavigator({
Home: { screen: HomeScreen },
// AllOthers: { screen: AllComponentsHereMayAccessScreenProps },
});
export default class App extends React.Component {
constructor() {
super();
this.state = {
everythingIsAwesome: false,
}
}
_updateGlobalState(payload) {
console.log('updating global state: ', payload);
this.setState({everythingIsAwesome: payload});
}
render() {
return <NavComponent screenProps={{
updateGlobalState: this._updateGlobalState.bind(this),
awesome: this.state.everythingIsAwesome
}} />;
}
}