未捕获的TypeError:无法读取未定义的reactjs的属性“state”

时间:2018-04-02 13:56:15

标签: javascript reactjs redux

我已经粘贴了我的整个代码,但是我无法解决问题。请查看此代码。

安慰时显示以下错误:

  

未捕获的TypeError:无法读取undefined reactjs的属性“state”

代码:

export class Login extends Component {
  constructor(props) {
    super(props);
    this.handleChangeforSignUp = this.handleChangeforSignUp.bind(this);
    this.createNewUserWithEmailPassword = this.createNewUserWithEmailPassword.bind(this);
    this.state = {
      sign_up_details: {
        email: "",
        password: "",
        confirmpassword: "",
        notification: ""
      }
    };
  }
  
    createNewUserWithEmailPassword(event){
    event.preventDefault();
    if((this.state.sign_up_details.password !== "") && (this.state.sign_up_details.confirmpassword !== "")){
      if(this.state.sign_up_details.password === this.state.sign_up_details.confirmpassword){
        let updateNotification = Object.assign({}, this.state.sign_up_details, {notification: "Password matched"});
        this.setState({
          sign_up_details: updateNotification
        });

        app.auth().createUserWithEmailAndPassword(this.state.sign_up_details.email, this.state.sign_up_details.password)
        .catch(function(error) {
          // Handle Errors here.
          let errorCode = error.code;
          console.log(errorCode);
          let errorMessage = error.message;
          if (errorCode == 'auth/weak-password') {
            let notify = Object.assign({}, this.state.sign_up_details, {notification: errorMessage});      
            this.setState({
              sign_up_details: notify
            });
          } else {
            // alert(errorMessage);
            let notify = Object.assign({}, this.state.sign_up_details, {notification: errorMessage});      
            this.setState({
              sign_up_details: notify
            },
            () => {
              console.log(this.state.sign_up_details);
            } );
          }
          console.log(error);
        }).then(
          function(onResolve, onReject){
            console.log(onResolve);
            console.log(onReject);
          }
        );

      }else{
        let notify = Object.assign({}, this.state.sign_up_details, {notification: "Password not matched"});
        this.setState({
          sign_up_details: notify
        });
      }
    }
  }
  
    handleChangeforSignUp(event){
    // console.log(event);
    const  target = event.target;
    let emailInput = "";
    let passwordInput = "";
    let confirmpasswordInput = "";
      
    if(target.type === 'email'){
      emailInput = target.value;
      let updateEmail = Object.assign({}, this.state.sign_up_details, {email: emailInput});
      this.setState({
        sign_up_details: updateEmail
      });

    }

    if(target.type === 'password' && target.name === 'password'){
      passwordInput = target.value;
      let updatePassword = Object.assign({}, this.state.sign_up_details, {password: passwordInput});      
      this.setState({
        sign_up_details: updatePassword
      });
    }

    if(target.type === 'password' && target.name === 'confirmpassword'){
      confirmpasswordInput = target.value;
      let updateConfirmpassword = Object.assign({}, this.state.sign_up_details, {confirmpassword: confirmpasswordInput});
      this.setState({
        sign_up_details: updateConfirmpassword
      });
    }
  }
  
  render() {
    
    const { from } = this.props.location.state || { from: { pathname: '/' } }
    //  const { from } = this.props.history.location || { from: { pathname: '/' } }
    
    if (this.state.redirect === true) {
      return <Redirect to={from} />
    }

    return (
        <div id="register" class="container tab-pane fade animated fadeIn">
          <form onSubmit={this.createNewUserWithEmailPassword} className="formfield" ref={(form) => { this.signupForm = form }} method="post">
              <h1 className="text-center login-heading pt-2 pb-4"><i className="fa fa-pencil fa-lg mx-2" ></i> Register</h1>
              {/* <input value={this.state.sign_up_details.name} onChange={this.handleChangeforSignUp}  className="form-control input mb-2" name="name" type="text" placeholder="John Doe" />               */}
              <input value={this.state.sign_up_details.email} onChange={this.handleChangeforSignUp}  className="form-control input mb-2" name="email" type="email" placeholder="john.doe@jd.com" />
              <input value={this.state.sign_up_details.password} onChange={this.handleChangeforSignUp}  className="form-control input mb-2" name="password" type="password" placeholder="*******" />
              <input value={this.state.sign_up_details.confirmpassword} onChange={this.handleChangeforSignUp}  className="form-control input mb-2" name="confirmpassword" type="password" placeholder="*******" />              
              <p className="text_ter text_pink">{this.state.sign_up_details.notification !== "" ? this.state.sign_up_details.notification : ""}</p>
              <input type="submit" className="btn btn-primary btn-sm btn-block p-2 mt-4 mb-2" value="Log In"></input>
          </form>
        </div>

     
    )
  }
}

ReactDOM.render(<Login/>, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.0/react-dom.min.js"></script>

<div id="app"><div>

enter image description here

2 个答案:

答案 0 :(得分:0)

您似乎正在使用react-router(例如,它为您提供Redirect组件),但它从未导入或包含在任何地方?

答案 1 :(得分:0)

因此,此错误等同于您写了undefined.state

看看您的事件处理程序(例如handleChangeForSignup()),您在命名时使用的是错误的做法,这不是完全驼峰的情况,您拥有handleChangeforSignup()

具体与此错误有关,请查看createNewUserWithEmailPassword()

您首先尝试通过以下方法对其进行测试:

createNewUserWithEmailPassword(event) {
    event.preventDefault();

    console.log(this.state.sign_up_details);
  }

您在这里看到另一个问题了吗?再次,命名约定。您需要此事件处理程序一次执行一件事情。您看到我添加的控制台日志不起作用了吗?它只会检查电子邮件,但是如果您首先进行此操作,那么您一次知道要执行一步,并在整个过程中测试代码,那么您可能会更早地收到此错误。

JavaScript认为createNewUserWithEmailPassword()内部不等于this,而是this等于未定义。

您需要查看this关键字在类内部的用途以及如何在函数内部确定this的值。

您的Login实例应具有一些不同的属性,例如staterender()createNewUserWithEmailPassword()

您应该能够引用关键字this,这是对类本身的引用。

因此,您是说给我引用我正在其中编写代码的Login实例。这样您就可以访问staterender()createNewUserWithEmailPassword()

我会像这样清理代码:

class Login extends React.Component {
  state = {
      sign_up_details: {
        email: "",
        password: "",
        confirmpassword: "",
        notification: ""
      }
    };
  }

除非您正在做import React, { Component } from 'react';,但您没有在帖子中添加,所以我做了React.Component

那么this为何在createNewUserWithEmailPassword()内部出错?

要了解这一点,我们需要很好地了解如何在函数内部确定this的值。

class Car {
    setDriveSound(){
    this.sound = sound;
  }

  drive() {
    return this.sound;
  }
}

这只是一个伪类,允许我们设置一个值,然后返回该值。

class Car {
    setDriveSound(sound){
    this.sound = sound;
  }

  drive() {
    return this.sound;
  }
}

const car = new Car();
car.setDriveSound('vroom');
car.drive();

这将输出vroom

因此,这是需要理解的重要规则。每当我们想弄清楚this的值将在类中的方法内部时,请不要查看方法本身,而应查看调用方法的位置。

在上面的示例中,我们看car.drive();

我们找到函数名称,在这种情况下为drive(),我们看向函数左侧的点,并查看其中引用的变量。

因此,this方法中来自return this.sound;的{​​{1}}将等于drive()类中的car变量。

因此,不要看函数,而看函数的调用位置。调用该函数时,圆点左侧是什么。

因此,在Car上调用drive()时,car等于this的实例。

我将创建一个名为car的对象,并从truck的实例中剥离drive()函数并将其分配给卡车对象:

car

这将返回const truck = { sound: "honk_honk", driveMyTruck: car.drive } truck.driveMyTruck(); ,因为在honk_honk函数中truck等于this

后者等效于:

drive()

让我们应用以上内容,以便根据您的情况进行操作。

现在,如果我尝试这样做:

drive() {
  return truck.sound;
}

现在我会得到const drive = car.drive; drive();

因此,当回调在某个时间点通过form元素传递时,我们将调用Cannot read property 'sound' of undefined,并且在调用它时,将没有createNewUserWithEmailPassword() Login

此处示例:

createNewUserWithEmailPassword

确实是您所做的或正在发生的事情。

这可能仍然令人困惑,这不是一个容易理解的概念,我也经常收到这类错误消息。

那么您将如何应用我刚刚解释的内容?

有几种方法可以解决您的问题。

现在,您为class Car { setDriveSound(sound){ this.sound = sound; } drive() { return this.sound; } } const car = new Car(); car.setDriveSound('vroom'); const drive = car.drive; drive(); 添加了一个constructor(props)方法,因为它扩展了super(props),并且您做了React.Component

这应该产生了该函数的新版本,并且应该使用正确的值this.createNewUserWithEmailPassword = this.createNewUserWithEmailPassword.bind(this);进行了修复,但是并不能解决问题。

所以尝试一下:

this