我如何在react类 Es6 的另一个方法中调用一个方法

IT技术 javascript reactjs ecmascript-6
2021-05-06 06:27:42

所以我基本上想做的很简单

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

编辑 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在 a 内部调用function,这会丢失外部this绑定。改用箭头函数:

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

进一步阅读:

我有一个类似的问题

我刚刚遇到了相同的错误消息的类似问题。奇怪的是,有时当我在另一个方法中调用一个方法时,它会起作用。我正在制作一个西蒙游戏,下面的方法在一个方法中有效。

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);只是为了看看这是什么。原来这是窗口对象。我不知道为什么,也许被埋没在 if/else 语句中。这两种方法都是绑定的,所以这不是问题。

无论如何。我在 window 对象中四处寻找,结果发现我可以使用this.App.prototype.handleGame();并且可以正常工作!我应该补充一点,我的主要 ES6 组件的名称是 App。这将根据您的组件和方法名称而有所不同,但总体原则仍应适用。

开发工具截图

我很震惊

我承认我是新手。这是我在 React 中的第二个迷你项目,但发现这是最酷的事情。现在可能还有其他方法,例如上面提到的箭头函数,但这对我有用。这就是玩游戏和直接垃圾之间的区别。希望这可以帮助某人。