Donc, ce que je suis en train d'essayer de faire est simple
class Something extends React.Component {
validateEmail () {
//code that validates email,innerHTML a div.status element if error occurs
this.removeStatus();//then remove status onkeydown of input element
}
removeStatus () {
//code that removes the status onkeydown of input element
}
}
pour une raison quelconque, cela ne fonctionne pas. dans ma console javascript (chrome) Je reçois ce message
login.js:132Uncaught TypeError: this.removeStatus is not a function
Edit 1: J'ai ajouté le code actuel, comme vous pouvez le constater, je lie validateEmail dans le constructeur.
class Email extends React.Component {
constructor(props) {
super(props);
this.change = this.change.bind(this);
this.validateEmail = this.validateEmail.bind(this);
this.state = {
value : ''
}
}
removeStatus() {
$('input').on('keydown',function () {
$('.contextual-info').fadeOut();
});
}
validateEmail(event) {
event.preventDefault();
var token = $('#token').val();
var email_regex=/^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i;
if ($.trim(this.state.value) !== "") {
if (email_regex.test(this.state.value)) {
$.ajax({
url:'/login',
type:'post',
data:{email:this.state.value,_token:token},
success: function (response) {
if (response) {
$('#email').remove();
$('.btn').remove();
$('#status').html('');
ReactDOM.render(<Password /> ,document.getElementById('login-dialogue'));
$('input[type="password"]').focus();
} else {
$('input#email').addClass('input-context');
if($('#status').html('<div class="bg-danger contextual-info wrong">Email Address Not Found!</p>')){
this.removeStatus();
}
}
}
});
} else {
if($('#status').html('<div class="bg-danger contextual-info wrong">Invalid Email Address</div>')){
this.removeStatus();
}
}
} else {
if($('#status').html('<div class="bg-danger contextual-info wrong">Can\'t submit an empty field!</div>')){
this.removeStatus();
}
}
}
change (event) {
this.setState({
value : event.target.value
});
}
render(){
return(
<div className="login-dialogue" id="login-dialogue">
<h1 className="text-center">Log in</h1>
<div id="status"></div>
<form action="" onSubmit={this.validateEmail} id="validateEmail">
<input type="email" id="email" value={this.state.value} placeholder="Email Address" onChange={this.change} />
<button type="submit" className="btn btn-flat btn-wide teal white-text">Continue</button>
</form>
</div>
);
}
}
ReactDOM.render(<Email /> ,document.getElementById('flex-me'));
Vos méthodes sont correctement définies. Le problème réside donc dans la façon dont vous appelezvalidateEmail
.
Vous l'invoquez d'une manière qui définit this
sur autre chose que votre instance Something
. Ceci est courant chez les auditeurs d'événements. Je suppose que vous avez un code comme celui-ci dans votre render
:
<button onClick={this.validateEmail} />
La solution recommandée pour React consiste à lier les gestionnaires d’événements de votre constructeur:
class Something extends React.Component {
constructor() {
super();
this.validateEmail = this.validateEmail.bind(this);
}
// ...
}
Vous pouvez également appeler la méthode depuis une fonction de flèche, qui conserve la valeur de this
à l'endroit où elle a été déclarée:
<button onClick={() => this.validateEmail()} />
L'inconvénient de cette approche est qu'un nouveau gestionnaire onClick
est créé chaque fois que votre composant est rendu.
EDIT: même problème, endroit différent. Vous appelez removeStatus
dans une function
, qui perd la liaison this
extérieure. Utilisez une fonction de flèche à la place:
$.ajax({
success: (response) => {
// etc
this.removeStatus();
}
})
Lectures complémentaires:
Je viens de rencontrer un problème similaire avec le même message d'erreur. Ce qui est étrange, c'est que parfois, lorsque j'appelle une méthode dans une autre méthode, cela fonctionne. Je fais un jeu de Simon et la méthode suivante dans une méthode fonctionne.
handleMouseDown (e) {
if(e.target.id==="green"){
$("#green").addClass("colorGreenPush");
greenSound.play();
clicked.Push(1);
this.handleCheck();
}
J'exécute simplement une méthode de vérification lorsque l'utilisateur appuie sur un bouton. Pas d'erreur.
handleCheck () {
var display = $("#display");
if(litID.length == clicked.length){
if(litID.join() == clicked.join()){
if(round == 20){
setTimeout(function(){
alert("Unreal. You Acually Won!!!");
location.reload();
},1000);
}
else{
setTimeout(function(){
display.text("-"+(round + 1)+"-");
round ++;
console.log(this);
litID = [];
clicked = [];
j = 0;
this.handleGame();
},1000);
}
}
Vers la fin, j'essaie this.handleGame();
et cela ne fonctionne pas.
Vous remarquerez que j'ai fait une console.log(this);
juste pour voir ce que c'était à ce stade. Il s'avère que c'était l'objet Window. Je ne sais pas pourquoi, peut-être être enterré dans des déclarations if/else. Les deux méthodes sont liées donc ce n'était pas le problème.
De toute façon. Je suis allé fouiller dans l'objet window et il s'avère que je peux utiliser this.App.prototype.handleGame();
et cela fonctionne! Je devrais ajouter que le nom de mon composant ES6 principal est App. Cela varie en fonction des noms de composant et de méthode, mais le principe général devrait toujours s'appliquer.
Je vais admettre que je suis un newb. C'est mon deuxième mini projet dans React, mais le trouver était la chose la plus cool. Maintenant, il peut y avoir d'autres moyens comme les fonctions de flèche mentionnées ci-dessus, mais c'est ce qui a fonctionné pour moi. Et c'était la différence entre avoir un jeu et avoir des ordures droites. J'espère que ça aide quelqu'un.