【问题标题】:Uncaught TypeError: Cannot read property 'state' of undefined reactjs未捕获的类型错误:无法读取未定义 reactjs 的属性“状态”
【发布时间】:2018-04-02 13:56:15
【问题描述】:

我已经粘贴了我的全部内容,这段代码中存在非常小的问题,但我无法解决问题。请查看此代码。

安慰时显示如下错误:

Uncaught TypeError: Cannot read property 'state' of undefined reactjs

代码:

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

【问题讨论】:

  • 您在哪一行遇到此问题?确保使用 this 的函数绑定到类。
  • 一旦进入catch,你的this就不会引用组件类,所以它没有任何状态。您应该在异步请求之外声明它,例如 let self = this.state 然后使用它。
  • 控制台在这块代码中的else { // alert(errorMessage); let notify = Object.assign({}, this.state.sign_up_details, {notification: errorMessage}); this.setState({ sign_up_details: notify }, () =&gt; { console.log(this.state.sign_up_details); } );上显示错误
  • @Ionut 谢谢,正在尝试

标签: javascript reactjs redux


【解决方案1】:

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

【讨论】:

  • 对不起,但重定向不是这个错误的一部分。 this.state.signup_details 有问题。它只是一个完整应用程序的一段代码。 @timotgl
  • 我可以在 Promise 中设置特定类的状态吗? @timotgl
  • @kropani 尝试更改方法,使组件在this. 的范围内:createNewUserWithEmailPassword = (event) =&gt; {} 与其他方法相同。
【解决方案2】:

所以这个错误相当于你写了undefined.state

查看您的事件处理程序,例如 handleChangeForSignup(),您在命名时使用了不好的做法,它不完全是驼峰式,您有 handleChangeforSignup()

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

您是否尝试通过以下方式先对其进行测试:

createNewUserWithEmailPassword(event) {
    event.preventDefault();

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

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

JavaScript 认为你的 createNewUserWithEmailPassword() 内部不等于 this,而是 this 等于 undefined。

您需要查看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

那么为什么thiscreateNewUserWithEmailPassword() 内部会出错?

要理解这一点,我们需要了解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(),我们查看函数左侧的点,并查看内部引用的变量。

因此,drive() 方法中 return this.sound; 中的 this 将等于 Car 类中的 car 变量。

所以,不要看函数,看函数调用的地方。当函数被调用时,点的左边是什么。

所以当drive()car 调用时,this 就等于car 的实例。

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

const truck = {
    sound: "honk_honk",
    driveMyTruck: car.drive
}

truck.driveMyTruck();

这将返回honk_honk,因为truck 等于thisdrive() 函数中。

后者相当于做:

drive() {
  return truck.sound;
}

让我们应用上述内容,看看你的情况。

现在如果我试试这个:

const drive = car.drive;

drive();

现在我会收到Cannot read property 'sound' of undefined

所以当回调在某个时间点传递给表单元素时,我们将调用createNewUserWithEmailPassword(),当它被调用时,没有LogincreateNewUserWithEmailPassword

这里是这个例子:

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

  drive() {
    return this.sound;
  }
}

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

const drive = car.drive;

drive();

正是你做了什么,或者你正在做什么。

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

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

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

现在,您添加了带有super(props)constructor(props) 方法,因为它扩展了React.Component,而您执行了this.createNewUserWithEmailPassword = this.createNewUserWithEmailPassword.bind(this);

这应该产生了一个新版本的函数,应该用正确的this值修复它,但它没有解决。

所以试试这个:

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

    createNewUserWithEmailPassword = (event) => {
       event.preventDefault();

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

【讨论】:

    猜你喜欢
    • 2022-01-01
    • 1970-01-01
    • 2016-08-09
    • 1970-01-01
    • 2023-03-21
    • 2017-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多