J'essaie de faire l'étape 15 de ce didacticiel ReactJS: React.js Introduction Pour les personnes qui en savent assez sur jQuery pour obtenir
L'auteur recommande ce qui suit:
overflowAlert: function() {
if (this.remainingCharacters() < 0) {
return (
<div className="alert alert-warning">
<strong>Oops! Too Long:</strong>
</div>
);
} else {
return "";
}
},
render() {
...
{ this.overflowAlert() }
...
}
J'ai essayé de faire ce qui suit (ce qui me semble bien):
// initialized "warnText" inside "getInitialState"
overflowAlert: function() {
if (this.remainingCharacters() < 0) {
this.setState({ warnText: "Oops! Too Long:" });
} else {
this.setState({ warnText: "" });
}
},
render() {
...
{ this.overflowAlert() }
<div>{this.state.warnText}</div>
...
}
Et j'ai reçu l'erreur suivante dans la console dans Chrome Dev Tools:
Mise à jour impossible lors d'une transition d'état existante (telle que dans
render
ou le constructeur d'un autre composant). Les méthodes de rendu doivent être une fonction pure d'accessoires et d'état; Les effets secondaires du constructeur sont un anti-pattern, mais peut être déplacé àcomponentWillMount
.
Voici une démo de JSbin . Pourquoi ma solution ne fonctionne-t-elle pas et que signifie cette erreur?
Votre solution fonctionne, car elle n’a aucun sens logique. L'erreur que vous recevez peut être un peu vague, alors laissez-moi la décomposer. La première ligne indique:
Mise à jour impossible lors d'une transition d'état existante (par exemple, dans le rendu ou le constructeur d'un autre composant).
Chaque fois que l'état d'un composant React est mis à jour, le composant est rendu au DOM. Dans ce cas, il y a une erreur car vous essayez d'appeler overflowAlert
dans render
, qui appelle setState
. Cela signifie que vous essayez de mettre à jour un état dans render qui appellera ensuite render et overflowAlert
et que vous mettrez à jour un état, puis appelez render, etc. conduisant à une boucle infinie. L'erreur vous indique que vous essayez de mettre à jour l'état en conséquence, ce qui a entraîné une boucle. C'est pourquoi cela n'est pas autorisé.
Au lieu de cela, prenez une autre approche et rappelez-vous ce que vous essayez d'accomplir. Essayez-vous d'avertir l'utilisateur lorsqu'il saisit du texte? Si tel est le cas, définissez overflowAlert
en tant que gestionnaire d'événements d'une entrée. De cette façon, l'état sera mis à jour lorsqu'un événement d'entrée se produit et le composant sera rendu à nouveau.
Assurez-vous que vous utilisez l'expression correcte. Par exemple, en utilisant:
<View onPress={this.props.navigation.navigate('Page1')} />
est différent avec
<View onPress={ () => this.props.navigation.navigate('Page1')} />
ou
<View onPress={ () => {
this.props.navigation.navigate('Page1')
}} />
Les deux derniers ci-dessus sont l'expression de la fonction, la première ne l'est pas. Assurez-vous que vous passez l'objet de fonction à l'expression de fonction () => {}
Au lieu d'effectuer une tâche liée à un composant dans la méthode de rendu, effectuez-le après la mise à jour du composant.
import React, { Component } from 'react';
import {
StyleSheet,
Text,
View,
Button,
Image,
} from 'react-native';
let timeoutid;
export default class Splash extends Component {
static navigationOptions = {
navbarHidden: true,
tabBarHidden: true,
};
constructor(props) {
super(props)
this.state = { navigatenow: false };
}
componentDidMount() {
timeoutid=setTimeout(() => {
this.setState({ navigatenow: true });
}, 5000);
}
componentWillUnmount(){
clearTimeout(timeoutid);
}
componentDidUpdate(){
const { navigate,goBack } = this.props.navigation;
if (this.state.navigatenow == true) {
navigate('Main');
}
}
render() {
//instead of writing this code in render write this code in
componenetDidUdpate method
/* const { navigate,goBack } = this.props.navigation;
if (this.state.navigatenow == true) {
navigate('Main');
}*/
return (
<Image style={{
flex: 1, width: null,
height: null,
resizeMode: 'cover'
}} source={require('./login.png')}>
</Image>
);
}
}