无法为此属性读取undefined的属性“状态”

时间:2020-07-21 05:55:53

标签: reactjs state react-dom

我是新来的反应者,我想知道为什么我不断得到这个无法读取“未定义”错误的属性值。当我用consolelog记录this.state.username和this.state.todoList时,我可以看到状态正在更新,但是只有在单击提交按钮后,它才会显示错误。

有什么建议吗?谢谢!

import React, { Component } from "react";
import axios from "axios";

export default class TestNote extends Component {
   constructor(props) {
   super(props);

   this.onChangeUsername = this.onChangeUsername.bind(this);
   this.onChangeTodoList = this.onChangeTodoList.bind(this);

   this.state = {
      username: "",
      todoList: "",
   };
}

onChangeUsername(e) {
   this.setState({
     username: e.target.value,
   });
   console.log(this.state.username);
}

onChangeTodoList(e) {
   this.setState({
     todoList: e.target.value,
   });
 }

 onSubmit(e) {
   e.preventDefault();

   const todoList = {
     username: this.state.username,
     todoList: this.state.todoList,
  };

console.log(todoList);

axios
  .post("http://localhost:5000/list/add", todoList)
  .then((res) => console.log(res.data));
 }

 render() {
   return (
     <div className="container">
       <form>
         <label>Username: </label>
         <input
           type="text"
           required
           value={this.state.username}
           onChange={this.onChangeUsername}
         />
         <label>TodoList: </label>
         <input
           type="text"
           value={this.state.todoList}
           onChange={this.onChangeTodoList}
         />
         <input type="submit" value="Add This List" onClick={this.onSubmit} />
       </form>
     </div>
   );
 }
}

3 个答案:

答案 0 :(得分:2)

您的onSubmit正在丢失此上下文。您应该尝试这些方法之一,但是我建议您使用箭头功能。

  • 您应.bind(this)onSubmit

...
<input type="submit" value="Add This List" onClick={this.onSubmit.bind(this)} />
...

  • onSubmit定义为箭头函数

...
onSubmit = (e) => {
 e.preventDefault();

 const todoList = {
   username: this.state.username,
   todoList: this.state.todoList,
 };
}
...

答案 1 :(得分:0)

您没有将onSubmit函数/方法绑定到this,因此this没有上下文,并且将返回未定义。您可以在构造函数中将this绑定到onSubmit来修复错误。

避免绑定this的另一种方法是对类方法/函数使用箭头函数,因为它们会自动将this绑定到该函数,您不必担心自己这样做

constructor(props) {
    super(props);
    this.state = {
       username: "",
       todoList: ""
    };

    //  this.onChangeUsername = this.onChangeUsername.bind(this);
    //  this.onChangeTodoList = this.onChangeTodoList.bind(this);

    //  this.onSubmit = this.onSubmit.bind(this);
  }

  onChangeUsername = e => {
    this.setState({
      username: e.target.value
    });
    console.log(this.state.username);
  };

  onChangeTodoList = e => {
    this.setState({
      todoList: e.target.value
    });
  };

  onSubmit = (e) => {
    e.preventDefault();

    const todoList = {
      username: this.state.username,
      todoList: this.state.todoList
   };

答案 2 :(得分:0)

在不使用arrow function的情况下在组件中定义函数时,必须将该函数绑定到构造函数中的this关键字,该函数才能在if定义中考虑this的每个引用引用创建的组件。

这是bind方法的定义

bind()方法创建一个新函数,该函数在被调用时将其关键字设置为提供的值,并在调用新函数时提供给定的参数序列。

因此,如果您有Home组件,则应这样定义

class Home extends React.Component {
    constructor(props)  {
      super(props);
      this.state = {
        name: "Jeanne Doe"
      }
    }
    
    handleChangeName () {
        this.setState({name: "John Doe"});
    }
    
    render() {
        return <div>
            <h2>Welcome {this.state.name}</h2>
            <button onClick={this.handleChangeName}>Change name</button>
        </div>
    }
}

ReactDOM.render(<Home />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.3.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.3.0/umd/react-dom.production.min.js"></script>
<div id="root"></div>

此处出现错误,提示您"TypeError: this is undefined"

要解决此问题,您必须像这样使用bind

class Home extends React.Component {

    constructor(props) {
      super(props)
      this.state = {
        name: "Jeanne Doe"
      }
      this.handleChangeName = this.handleChangeName.bind(this);
    }
    handleChangeName () {
        this.setState({name: "John Doe"});
    }
    
    render() {
        return <div>
            <h2>Welcome {this.state.name}</h2>
            <button onClick={this.handleChangeName}>Change name</button>
        </div>
    }
}

ReactDOM.render(<Home />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

<div id="root"></div>

或者为了完全避免使用bind,因为您可以在组件中定义许多方法,因此可以使用如下所示的arrow function

class Home extends React.Component {
    constructor(props)  {
      super(props);
      this.state = {
        name: "Jeanne Doe"
      }
    }

    const handleChangeName = () => {
        this.setState({name: "John Doe"});
    }

    render() {
        return <div>
            <h2>Welcome {this.state.name}</h2>
            <button onClick={this.handleChangeName}>Change name</button>
        </div>
    }
}