Как вызвать метод в другом методе в классе react Es6

Так что я в основном пытаюсь сделать, это просто

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

 }
}

по какой-то причине это не работает. в моей консоли javascript (chrome) я получаю это

login.js:132Uncaught TypeError: this.removeStatus is not a function

Edit 1: я добавил фактический код, как вы можете видеть, я связываю validateEmail в конструкторе

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'));

2 ответов


ваши методы определены правильно, поэтому проблема заключается в том, как вы вызов validateEmail.

вы вызываете его в this к чему-то, кроме вашего Something экземпляра. Это распространено в прослушивателей событий. Я думаю, у вас есть такой код в вашем render:

<button onClick={this.validateEmail} /> 

на рекомендуемое решение для React-привязать обработчики событий в вашем конструкторе:

class Something extends React.Component {

  constructor() {
    super();
    this.validateEmail = this.validateEmail.bind(this);
  }

  // ...
}

вы также можете вызвать метод изнутри функции стрелки, которая сохраняет значение this на месте было объявлено:

<button onClick={() => this.validateEmail()} /> 

недостатком этого подхода является то, что новый onClick обработчик создается каждый раз при визуализации компонента.


редактировать: та же проблема, другое место. Вы звоните removeStatus внутри function, который теряет внешний this привязка. Вместо этого используйте функцию стрелки:

$.ajax({
  success: (response) => { 
    // etc
    this.removeStatus();
  }
})

далее чтение:


у меня была аналогичная проблема

Я просто столкнулся с аналогичной проблемой с тем же сообщением об ошибке. Странно то, что иногда, когда я вызываю метод внутри другого метода, он работает. Я делаю игру Simon, и следующий метод в методе работает.

handleMouseDown (e) {
    if(e.target.id==="green"){
    $("#green").addClass("colorGreenPush");
      greenSound.play();
      clicked.push(1);
      this.handleCheck();
    } 

Я просто запускаю метод проверки, когда пользователь нажимает кнопку. Никакая ошибка.

однако я получал TypeError с этим кодом

 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);
        }
      } 

ближе к концу я попробовать this.handleGame(); и это не сработало.

Мое Решение

вы заметите, что я сделал console.log(this); просто чтобы посмотреть, что это было в этот момент. Оказывается, это был объект Window. Я не знаю, почему, возможно, похоронен в заявлениях if/else. Оба метода связаны, так что проблема не в этом.

абы. Я пошарил в окне объекта и оказалось, что я могу использовать this.App.prototype.handleGame(); и это работает! Я должен добавить, что имя моего основного компонента ES6-приложение. Это будет отличаться на основе ваших имен компонентов и методов, но общий принцип все равно должен применяться.

Dev Tools Screenshot

Я В Шоке

Я признаю, что я новенькая. Это мой второй мини-проект в React, но найти это было самое крутое. Теперь могут быть другие способы, такие как функции стрелки, упомянутые выше, но это то, что сработало для меня. И это была разница между игрой и прямым мусором. Надеюсь, это поможет кто-то.