简体   繁体   English

无法读取 this.state 的未定义属性“状态”

[英]Cannot Read Property 'state' of undefined for this.state

I'm new to react and I was wonder why I keep getting this cannot read property value of "undefined" error.我是新来的反应,我想知道为什么我一直得到这个无法读取“未定义”错误的属性值。 When i consolelog the this.state.username and this.state.todoList I can see that states updating but only after I clicked the submit button it gives me the error.当我控制台记录 this.state.username 和 this.state.todoList 时,我可以看到状态正在更新,但只有在我单击提交按钮后才会出现错误。

Any suggestions?有什么建议么? Thank you!谢谢!

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

Your onSubmit are losing this context.你的onSubmit正在失去这个上下文。 You should try one of these methods, but I recommend you using arrow function.您应该尝试其中一种方法,但我建议您使用箭头 function。

  • You should .bind(this) to onSubmit你应该.bind(this)onSubmit

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

  • Defined onSubmit as an arrow functiononSubmit定义为箭头 function

 ... onSubmit = (e) => { e.preventDefault(); const todoList = { username: this.state.username, todoList: this.state.todoList, }; }...

You did not bind onSubmit function/method to this , therefore this has no context and would return undefined.您没有将onSubmit函数/方法绑定到this ,因此this没有上下文并且将返回未定义。 You can bind this to onSubmit in the constructor to fix the error.您可以将this绑定到构造函数中的onSubmit以修复错误。

Another way to avoid having to bind this is to use arrow functions for your class methods/functions as they automatically bind this to that function, you won't have to worry about doing it yourself.避免绑定this的另一种方法是为您的 class 方法/函数使用箭头函数,因为它们会自动将this绑定到 function,您不必担心自己做。

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

When you define function in your component without using arrow function you have to bind to each function the this keyword in the constructor for that function to consider each reference of this in if definition to refer to the created component. When you define function in your component without using arrow function you have to bind to each function the this keyword in the constructor for that function to consider each reference of this in if definition to refer to the created component.

Here is the definition of the bind method这是bind方法的定义

The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called. bind() 方法创建一个新的 function,当调用它时,它的 this 关键字设置为提供的值,在调用新的 ZC1C425268E68385D1AB5074C17A94F1 时,给定的 arguments 序列在任何提供的序列之前。

So if you have component Home define like this因此,如果您有这样的组件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>

Here you get the error that tell you "TypeError: this is undefined"在这里你会得到一个错误,告诉你"TypeError: this is undefined"

So to fix that you have to use bind like this所以要解决这个问题,你必须像这样使用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>

Or to completely avoid the use of bind as you can have so many methods define in your component you can use arrow function which look like this或者为了完全避免使用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>
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM