【问题标题】:Cannot Read Property 'state' of undefined for this.state无法读取 this.state 的未定义属性“状态”
【发布时间】:2020-11-10 11:07:07
【问题描述】:

我是新手,我想知道为什么我一直收到无法读取“未定义”错误的属性值。当我对 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>
   );
 }
}

【问题讨论】:

  • 您还需要将this 绑定到您的onSubmit 处理程序,即this.onSubmit = this.onSubmit.bind(this); 或将onSubmit 转换为箭头函数以便this 绑定自动 .
  • 除了@DrewReese 提到的,你也可以使用不用每次都绑定的es6。 onSubmit = (e) =&gt; {...}
  • 好的,这似乎有效。谢谢!

标签: reactjs state react-dom


【解决方案1】:

您的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,
 };
}
...

【讨论】:

  • 第一个解决方案有效,它给我一个关于我的后端的错误,这意味着前端正在工作,但第二个解决方案不是我已经拥有的吗?使用箭头函数有影响吗?
  • 您的两个 sn-ps 都有语法错误,因此无法运行。
  • @DrewReese 哪里有语法错误?我很难将代码放在堆栈溢出上,但似乎有任何语法错误引起了我的注意。
  • 你试过运行你的 sn-ps 吗?只需使用代码块与可运行代码 sn-p 块。
【解决方案2】:

当您在组件中定义函数而不使用 arrow function 时,您必须将构造函数中的 this 关键字绑定到每个函数,以便该函数考虑 if 定义中对 this 的每个引用来引用创建的组件.

这里是bind方法的定义

bind() 方法创建一个新函数,在调用该函数时,将其 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>

在这里你会看到告诉你的错误"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>
    }
}

【讨论】:

    【解决方案3】:

    您没有将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
       };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-08
      • 2021-11-28
      • 2019-07-25
      • 2020-11-05
      • 2021-07-07
      • 1970-01-01
      相关资源
      最近更新 更多